Commit 7716f8c7 authored by Devon Kearns's avatar Devon Kearns

Imported Upstream version 5.4.1-rc1

parents
T50 was created by Nelson Brito <nbrito@sekure.org> and is
mantained by Fernando Mercês <fernando@mentebinaria.com.br>, with
support of some contributors:
Frederico Pissara <fredericopissara@gmail.com>
T50 - Experimental Mixed Packet Injector
Legend:
+ Added feature
* Improved/changed feature
- Bug fixed
! Known issue / missing feature
T50 5.4.1 - November 26, 2011 - thanks to Frederico Pissara!
- Fixed bug in option parsing.
- Fixed licensing miss in some files.
* Improved code, reduced memory consumption.
* Improved Makefile, reduced compilation time, use of SS3 instructions.
- Manpage moved to section 8.
+ Strip set by default.
T50 5.4.0 - September 4, 2011
+ New version scheme <MajorVersion.MinorVersion.RevisionNumber>.
+ Added manpage.
* UPX and strip removed.
* License limitations removed.
* Removed libmath dependency.
* New smaller Makefile reducing compile time. Many flags removed.
! We don't have support for IPv6 yet.
! T50 may not compile in other systems nor GNU/Linux distros.
T50 5.3 - April 9, 2011
+ New License: it is, finally, licensed under GPL v2.0. Please, refer
to LICENSE document for further information.
+ CIDR Support: Classless Inter-Domain Routing support for destination
IP address, using a really tiny C algorithm. This would allow
the new version to simulate DDoS in a laboratory environment.
+ New protocols support: IGMP, EGP, RIP, DCCP, RSVP, IPSec, GRE, EIGRP
and OSPF.
+ TCP Options support.
T50 3.4 - November 10, 2010
First public release.
This diff is collapsed.
___________._______________
\__ ___/| ____/\ _ \ T50: an Experimental Packet Injector Tool
| | |____ \ / /_\ \
| | / \\ \_/ \
|____| /______ / \_____ / Copyright (c) 2001-2011 Nelson Brito
\/ \/ All Rights Reserved
T50 Experimental Mixed Packet Injector (f.k.a. F22 Raptor) is a tool designed
to perform "Stress Testing". The concept started on 2001, right after release
'nb-isakmp.c', and the main goal was:
- Having a tool to perform TCP/IP protocol fuzzer, covering common regular
protocols, such as: ICMP, TCP and UDP.
Things have changed, and the T50 became a good unique resource capable to
perform "Stress Testing". And, after checking the "/usr/include/linux", some
protocols were chosen to be part of its coverage:
a) ICMP - Internet Control Message Protocol
b) IGMP - Internet Group Management Protocol
c) TCP - Transmission Control Protocol
d) UDP - User Datagram Protocol
Why "Stress Testing"? Well, because when people are designing a new network
infra-structure (eg. Datacenter serving to Cloud Computing) they think about:
a) High-Availability
b) Load Balancing
c) Backup Sites (Cold Sites, Hot Sites, and Warm Sites)
d) Disaster Recovery
e) Data Redundancy
f) Service Level Agreements
g) Etc...
But almost nobody thinks about "Stress Testing", or even performs any test to
check how the networks infra-structure behaves under stress, under overload,
and under attack. Even during a Penetration Test, people prefer not running
any kind of Denial-of-Service testing. Even worse, those people are missing
one of the three key concepts of security that are common to risk management:
- Confidentiality
- Integrity
- AVAILABILITY
T50 was designed to perform “Stress Testing” on a variety of infra-structure
network devices (Version 2.45), using widely implemented protocols, and after
some requests it was was re-designed to extend the tests (as of Version 5.3),
covering some regular protocols (ICMP, TCP and UDP), some infra-structure
specific protocols (GRE, IPSec and RSVP), and some routing protocols (RIP,
EIGRP and OSPF).
This new version (Version 5.3) is focused on internal infra-structure, which
allows people to test the availability of its resources, and cobering:
a) Interior Gateway Protocols (Distance Vector Algorithm):
1. Routing Information Protocol (RIP)
2. Enhanced Interior Gateway Routing Protocol (EIGRP)
b) Interior Gateway Protocols (Link State Algorithm):
1. Open Shortest Path First (OSPF)
c) Quality-of-Service Protocols:
1. Resource ReSerVation Protocol (RSVP).
d) Tunneling/Encapsulation Protocols:
1. Generic Routing Encapsulation (GRE).
T50 is a powerful and unique packet injector tool, which is capable to:
a) Send sequentially the following fifteen (15) protocols:
1. ICMP - Internet Control Message Protocol
2. IGMPv1 - Internet Group Management Protocol v1
3. IGMPv3 - Internet Group Management Protocol v3
4. TCP - Transmission Control Protocol
5. EGP - Exterior Gateway Protocol
6. UDP - User Datagram Protocol
7. RIPv1 - Routing Information Protocol v1
8. RIPv2 - Routing Information Protocol v2
9. DCCP - Datagram Congestion Control Protocol
10. RSVP - Resource ReSerVation Protocol
11. GRE - Generic Routing Encapsulation
12. IPSec - Internet Protocol Security (AH/ESP)
13. EIGRP - Enhanced Interior Gateway Routing Protocol
14. OSPF - Open Shortest Path First
b) It is the only tool capable to encapsulate the protocols (listed above)
within Generic Routing Encapsulation (GRE).
c) Send an (quite) incredible amount of packets per second, making it a
"second to none" tool:
-> More than 1,000,000 pps of SYN Flood (+50% of the network uplink) in
a 1000BASE-T Network (Gigabit Ethernet).
-> More than 120,000 pps of SYN Flood (+60% of the network uplink) in a
100BASE-TX Network (Fast Ethernet).
d) Perform "Stress Testing" on a variety of network infrastructure, network
devices and security solutions in place.
e) Simulate "Distributed Denial-of-Service" & "Denial-of-Service" attacks,
validating Firewall rules, Router ACLs, Intrusion Detection System and
Intrusion Prevention System policies.
The main differentiator of the T50 is that it is able to send all protocols,
sequentially, using one single SOCKET, besides it is capable to be used to
modify network routes, letting IT Security Professionals performing advanced
"Penetration Test".
5.4.1-rc1
# T50 Makefile
#
# Written by Fernando Mercês <fernando@mentebinaria.com.br>
#
# __HAVE_TURBO__ - turbo mode enable --turbo option. This makes
# T50 create a child process to improve performance.
#
# __HAVE_DEBUG__ - debug mode makes T50 print the source filename
# and line when an error occurs. This is a good idea if you're
# experiencing problems.
PREFIX=/usr
MANDIR=/usr/share/man/man8
SRCDIR=.
CC=gcc
USE_SSE=-msse -mfpmath=sse
STRIP=-s
CFLAGS=-W -Wall -Wextra -O3 $(USE_SSE) -ffast-math $(STRIP)
INCLUDES=-I$(SRCDIR)/include
DFLAGS=-D__HAVE_TURBO__ -DVERSION=\"$(shell cat ../VERSION)\"
#DFLAGS+=-D__HAVE_DEBUG__
SRC=$(shell find $(SRCDIR) -type f -name '*.c')
all:
$(CC) $(CFLAGS) $(INCLUDES) $(DFLAGS) $(SRC) -o t50
clean:
rm -f t50
install:
install t50 $(PREFIX)/sbin
gzip -c -9 ../t50.1 > $(MANDIR)/t50.8.gz
uninstall:
rm -f $(PREFIX)/sbin/t50
/*
* T50 - Experimental Mixed Packet Injector
*
* Copyright (C) 2010 - 2011 Nelson Brito <nbrito@sekure.org>
* Copyright (C) 2011 - Fernando Mercês <fernando@mentebinaria.com.br>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <common.h>
/* Validate options */
int checkConfigOptions(const struct config_options *o)
{
/* Warning missed privileges. */
if ( getuid() )
{
ERROR("you must have privileges to run me");
return 0;
}
/* Warning missed target. */
if (o->ip.daddr == INADDR_ANY)
{
ERROR("try --help for usage and help");
return 0;
}
/* Sanitizing the CIDR. */
if ( (o->bits < CIDR_MINIMUM || o->bits > CIDR_MAXIMUM) && o->bits != 0)
{
char errstr[48];
sprintf(errstr, "CIDR must be beewten %d and %d",
CIDR_MINIMUM, CIDR_MAXIMUM);
ERROR(errstr);
return 0;
}
/* Sanitizing the TCP Options SACK_Permitted and SACK Edges. */
if ( (o->tcp.options & TCP_OPTION_SACK_OK) == TCP_OPTION_SACK_OK &&
(o->tcp.options & TCP_OPTION_SACK_EDGE) == TCP_OPTION_SACK_EDGE )
{
ERROR("TCP options SACK-Permitted and SACK Edges are not allowed");
return 0;
}
/* Sanitizing the TCP Options T/TCP CC and T/TCP CC.ECHO. */
if ((o->tcp.options & TCP_OPTION_CC) == TCP_OPTION_CC && (o->tcp.cc_echo) )
{
ERROR("TCP options T/TCP CC and T/TCP CC.ECHO are not allowed");
return 0;
}
/* Testing IANA IP address allocation for private internets (RFC 1700, 1918 and 3330). */
switch(ntohl(o->ip.daddr) & 0xff000000)
{
/* Allowing 10/8 (RFC 1918). */
case 0x0a000000: break;
/* Allowing 127/8 (RFC 1700). */
case 0x7f000000: break;
/* Allowing 169.254/16 (RFC 3330). */
case 0xa9000000:
if ((ntohl(o->ip.daddr) & 0xffff0000) != 0xa9fe0000)
{
fprintf(stderr, "T50 is RFC 1700, RFC 1918 and RFC 3330 compliance\n");
fflush(stderr);
return 0;
}
break;
/* Allowing 172.16/12 (RFC 1918). */
case 0xac000000:
if ((ntohl(o->ip.daddr) & 0xffff0000) < 0xac100000 || \
(ntohl(o->ip.daddr) & 0xffff0000) > 0xac1f0000)
{
fprintf(stderr, "T50 is RFC 1700, RFC 1918 and RFC 3330 compliance\n");
fflush(stderr);
return 0;
}
break;
/* Allowing 192.168/16 (RFC 1918). */
case 0xc0000000:
if ((ntohl(o->ip.daddr) & 0xffff0000) != 0xc0a80000)
{
fprintf(stderr, "T50 is RFC 1700, RFC 1918 and RFC 3330 compliance\n");
fflush(stderr);
return 0;
}
break;
/* Blocking all other IP addresses. */
default:
fprintf(stderr, "T50 is RFC 1700, RFC 1918 and RFC 3330 compliance\n");
fflush(stderr);
return 0;
break;
}
#ifdef __HAVE_TURBO__
/* Sanitizing TURBO mode. */
if (o->turbo && o->flood == 0)
{
ERROR("turbo mode is only available in flood mode");
return 0;
}
#endif /* __HAVE_TURBO__ */
/* Sanitizing the threshold. */
if (o->ip.protocol == IPPROTO_T50 && o->threshold < T50_THRESHOLD_MIN
&& o->flood == 0)
{
fprintf(stderr,
"%s: protocol %s cannot have threshold smaller than %d\n",
PACKAGE,
mod_acronyms[o->ip.protoname],
T50_THRESHOLD_MIN);
fflush(stderr);
return 0;
}
/* Warning FLOOD mode. */
if (o->flood)
{
printf("entering in flood mode...\n");
#ifdef __HAVE_TURBO__
if (o->turbo) printf("activating turbo...\n");
#endif /* __HAVE_TURBO__ */
/* Warning CIDR mode. */
if (o->bits) printf("performing DDoS...\n");
printf("hit CTRL+C to break.\n");
}
/* Returning. */
return 1;
}
/*
* T50 - Experimental Mixed Packet Injector
*
* Copyright (C) 2010 - 2011 Nelson Brito <nbrito@sekure.org>
* Copyright (C) 2011 - Fernando Mercês <fernando@mentebinaria.com.br>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <common.h>
static struct cidr cidr = { 0, 0 };
/* CIDR configuration tiny C algorithm */
struct cidr *config_cidr(uint32_t bits, in_addr_t address)
{
uint32_t netmask;
/* Configuring CIDR IP addresses. */
if (bits)
{
/*
* @nbrito -- Thu Dec 23 13:06:39 BRST 2010
* Here is a description of how to calculate, correctly, the number of
* hosts and IP addresses based on CIDR -- three instructions line.
*
* (1) Calculate the 'Network Mask' (two simple operations):
* a) Bitwise shift to the left (>>) '0xffffffff' using CIDR gives the
* number of bits to calculate the 'Network Mask'.
* b) Bitwise logic NOT (~) to turn off the bits that are on, and turn
* on the bits that are off gives the 'Network Mask'.
*
* (2) Calculate the number of hosts' IP addresses available to the
* current CIDR (two simple operations):
* a) Subtract CIDR from 32 gives the host identifier's (bits) portion
* for the IP address.
* b) Two raised to the power (pow(3)) of host identifier (bits) gives
* the number of all IP addresses available for the CIDR .
* NOTE: Subtracting two from this math skips both 'Network Address'
* and 'Broadcast Address'.
*
* (3) Calculate initial host IP address (two simple operations):
* a) Convert IP address to little-endian ('ntohl()').
* b) Bitwise logic AND (&) of host identifier (bits) portion of the IP
* address and 'Network Mask' adding one gives the first IP address
* for the CIDR.
*/
netmask = ~(0xffffffffUL >> bits);
cidr.hostid = (uint32_t) (1 << (32 - bits)) - 2;
cidr.__1st_addr = (ntohl(address) & netmask) + 1;
/* XXX Sanitizing the maximum host identifier's IP addresses.
* XXX Should never reaches here!!! */
if (cidr.hostid > MAXIMUM_IP_ADDRESSES)
{
ERROR("internal error detecded -- please, report");
ERROR("cidr.hostid > MAXIMUM_IP_ADDRESSES: Probably a specific platform error");
exit(EXIT_FAILURE);
}
}
return &cidr;
}
/*
* T50 - Experimental Mixed Packet Injector
*
* Copyright (C) 2010 - 2011 Nelson Brito <nbrito@sekure.org>
* Copyright (C) 2011 - Fernando Mercês <fernando@mentebinaria.com.br>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <common.h>
/* Calculates checksum */
uint16_t cksum(uint16_t * data, int32_t length)
{
int32_t nleft = length;
uint16_t *w = data;
int32_t sum = 0;
/* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits. */
while(nleft > 1)
{
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if(nleft == 1)
sum += *(uint8_t *)w;
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
/* returning sum truncated to 16 bits */
return ~sum;
}
/*
* T50 - Experimental Mixed Packet Injector
*
* Copyright (C) 2010 - 2011 Nelson Brito <nbrito@sekure.org>
* Copyright (C) 2011 - Fernando Mercês <fernando@mentebinaria.com.br>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <common.h>
char *mod_acronyms[] = {
"ICMP",
"IGMPv1",
"IGMPv3",
"TCP",
"EGP",
"UDP",
"RIPv1",
"RIPv2",
"DCCP",
"RSVP",
"IPSEC",
"EIGRP",
"OSPF",
"T50",
NULL
};
char *mod_names[] = {
"Internet Control Message Protocol",
"Internet Group Message Protocol v1",
"Internet Group Message Protocol v3",
"Transmission Control Protocol",
"Exterior Gateway Protocol",
"User Datagram Protocol",
"Routing Information Protocol v1",
"Routing Information Protocol v2",
"Datagram Congestion Control Protocol",
"Resource ReSerVation Protocol",
"Internet Protocol Security (AH/ESP)",
"Enhanced Interior Gateway Routing Protocol",
"Open Shortest Path First",
NULL
};
/* NOTE: This routine cannot be inlined due to its compliexity. */
uint32_t NETMASK_RND(uint32_t foo)
{
uint32_t t;
if (foo != INADDR_ANY)
t = foo;
else
t = ~(0xffffffffUL >> (8 + ((rand() >> 27) % 23)));
return htonl(t);
}
This diff is collapsed.
/*
* T50 - Experimental Packet Injector
*
* Copyright (C) 2010 - 2011 Nelson Brito <nbrito@sekure.org>
* Copyright (C) 2011 - Fernando Mercês <fernando@mentebinaria.com.br>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __COMMON_H
#define __COMMON_H
#define PACKAGE "T50"
#define SITE "http://t50.sf.net"
#if !(linux) || !(__linux__)
# error "Sorry! The t50 was only tested under Linux!"
#endif /* __linux__ */
#include <time.h>
#include <stdio.h>
#include <stdint.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <getopt.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/resource.h>
/* This code prefers to use Linux headers rather than BSD favored */
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/icmp.h>
#include <linux/igmp.h>
#include <linux/dccp.h>
#include <linux/if_ether.h>
/* Purpose-built config library to be used by T50 modules */
#include <config.h>
/* Purpose-built protocol libraries to be used by T50 modules */
#include <protocol/egp.h>
#include <protocol/gre.h>
#include <protocol/rip.h>
#include <protocol/igmp.h>
#include <protocol/ospf.h>
#include <protocol/rsvp.h>
#include <protocol/eigrp.h>
#include <protocol/tcp_options.h>
/* NOTE: This will do nothing. Used only to prevent warnings. */
#define UNUSED_PARAM(x) { (x) = (x); }
/* Data types */
typedef uint32_t in_addr_t;
typedef int socket_t;
/* Limits */
/* #define RAND_MAX 2147483647 */ /* NOTE: Already defined @ stdlib.h */
#define CIDR_MINIMUM 8
#define CIDR_MAXIMUM 30
#define MAXIMUM_IP_ADDRESSES 16777215
/* #define INADDR_ANY ((in_addr_t) 0) */ /* NOTE: Already defined @ linux/in.h */
#define IPPORT_ANY ((uint16_t) 0)
extern char *mod_acronyms[];
extern char *mod_names[];
/* OBS: Used only in config.c.
Isn't better to move this definitions?! */
enum t50_module
{
MODULE_ICMP = 0,
#define MODULE_ICMP MODULE_ICMP
MODULE_IGMPv1,
#define MODULE_IGMPv1 MODULE_IGMPv1
MODULE_IGMPv3,
#define MODULE_IGMPv3 MODULE_IGMPv3
MODULE_TCP,
#define MODULE_TCP MODULE_TCP
MODULE_EGP,
#define MODULE_EGP MODULE_EGP
MODULE_UDP,
#define MODULE_UDP MODULE_UDP
MODULE_RIPv1,
#define MODULE_RIPv1 MODULE_RIPv1
MODULE_RIPv2,
#define MODULE_RIPv2 MODULE_RIPv2
MODULE_DCCP,
#define MODULE_DCCP MODULE_DCCP
MODULE_RSVP,
#define MODULE_RSVP MODULE_RSVP
MODULE_IPSEC,
#define MODULE_IPSEC MODULE_IPSEC
MODULE_EIGRP,
#define MODULE_EIGRP MODULE_EIGRP
MODULE_OSPF,
#define MODULE_OSPF MODULE_OSPF
MODULE_T50,
# define MODULE_T50 MODULE_T50
# define T50_THRESHOLD_MIN MODULE_T50
};
/* Global common protocol definitions used by code */
#define AUTH_TYPE_HMACNUL 0x0000
#define AUTH_TYPE_HMACMD5 0x0002
#define AUTH_TLEN_HMACMD5 16
#define AUTH_TLEN_HMACMD5 16
#define auth_hmac_md5_len(foo) ((foo) ? AUTH_TLEN_HMACMD5 : 0)
#define IPVERSION 4
#define IP_MF 0x2000
#define IP_DF 0x4000
/* T50 DEFINITIONS. */
#define IPPROTO_T50 69
#define FIELD_MUST_BE_NULL NULL
#define FIELD_MUST_BE_ZERO 0
/* Common protocol structures used by code */
/*
* User Datagram Protocol (RFC 768)
*
* Checksum is the 16-bit one's complement of the one's complement sum of a
* pseudo header of information from the IP header, the UDP header, and the
* data, padded with zero octets at the end (if necessary) to make a
* multiple of two octets.
*
* The pseudo header conceptually prefixed to the UDP header contains the
* source address, the destination address, the protocol, and the UDP
* length. This information gives protection against misrouted datagrams.
* This checksum procedure is the same as is used in TCP.
*
* 0 7 8 15 16 23 24 31
* +--------+--------+--------+--------+
* | source address |
* +--------+--------+--------+--------+
* | destination address |
* +--------+--------+--------+--------+
* | zero |protocol| UDP length |
* +--------+--------+--------+--------+
*
* If the computed checksum is zero, it is transmitted as all ones (the
* equivalent in one's complement arithmetic). An all zero transmitted
* checksum value means that the transmitter generated no checksum (for
* debugging or for higher level protocols that don't care).
*/
struct psdhdr
{
in_addr_t saddr; /* source address */
in_addr_t daddr; /* destination address */
uint8_t zero; /* must be zero */
uint8_t protocol; /* protocol */
uint16_t len; /* header length */
};
/* Common macros used by code */
#define __32BIT_RND(foo) ((foo) == 0 ? (uint32_t)rand() : (uint32_t)(foo))
#define __24BIT_RND(foo) ((foo) == 0 ? rand() >> 8 : (foo))
#define __16BIT_RND(foo) ((foo) == 0 ? rand() >> 16 : (foo))
#define __8BIT_RND(foo) ((foo) == 0 ? rand() >> 24 : (foo))
#define __7BIT_RND(foo) ((foo) == 0 ? rand() >> 25 : (foo))
#define __6BIT_RND(foo) ((foo) == 0 ? rand() >> 26 : (foo))
#define __5BIT_RND(foo) ((foo) == 0 ? rand() >> 27 : (foo))
#define __4BIT_RND(foo) ((foo) == 0 ? rand() >> 28 : (foo))
#define __3BIT_RND(foo) ((foo) == 0 ? rand() >> 29 : (foo))
#define __2BIT_RND(foo) ((foo) == 0 ? (uint32_t)(rand() >> 30) : (uint32_t)(foo))
#define INADDR_RND(foo) __32BIT_RND(foo)
#define IPPORT_RND(foo) __16BIT_RND(foo)
extern uint32_t NETMASK_RND(uint32_t);
#ifdef __HAVE_DEBUG__
#define ERROR(s) \
fprintf(stderr, "%s: %s at %s, line %d\n", PACKAGE, s, __FILE__, \
__LINE__); fflush(stderr);
#else
#define ERROR(s) fprintf(stderr, "%s: %s\n", PACKAGE, s); fflush(stderr);
#endif
/* Common routines used by code */
extern struct cidr *config_cidr(uint32_t, in_addr_t);
/* Command line interface options validation. */
extern int checkConfigOptions(const struct config_options *);
/* Checksum calculation. */
extern uint16_t cksum(uint16_t *, int32_t);
/* Command line interface options configuration. */
extern struct config_options *getConfigOptions(int, char **);
/* IP address and name resolve. */
extern in_addr_t resolv(char *);
/* Socket configuration. */
extern socket_t sock(void);
/* Help and usage message. */
extern void usage(void);
/* Common module routines used by code */
/* Function Name: ICMP packet header configuration. */
extern void icmp (const socket_t, const struct config_options *);