Commit 17d902a1 authored by Robert Ricci's avatar Robert Ricci

Added a new script: whol = Whack on LAN.

Sends wake-on-lan packets to a speicifc MAC address in order to
trigger our custom whack-on-lan hardware.
parent e4c50605
......@@ -23,7 +23,7 @@ include Makeconf
#
SUBDIRS = lib db assign www @optional_subdirs@ ipod security sensors \
pxe tbsetup account tmcd utils tip capture ipod vis \
sensors os xmlrpc install/newnode_sshkeys mote
sensors os xmlrpc install/newnode_sshkeys mote tools/whol
all: all-subdirs
......
......@@ -2239,7 +2239,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
rc.d/2.elvind.sh rc.d/3.plab.sh rc.d/2.dhcpd.sh \
tools/GNUmakefile \
tools/pcapper/GNUmakefile tools/teachswitch/GNUmakefile \
tools/webcamapplet/GNUmakefile \
tools/webcamapplet/GNUmakefile tools/whol/GNUmakefile \
$eventfiles \
$winfiles \
apache/GNUmakefile apache/httpd.conf \
......
......@@ -734,7 +734,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
rc.d/2.elvind.sh rc.d/3.plab.sh rc.d/2.dhcpd.sh \
tools/GNUmakefile \
tools/pcapper/GNUmakefile tools/teachswitch/GNUmakefile \
tools/webcamapplet/GNUmakefile \
tools/webcamapplet/GNUmakefile tools/whol/GNUmakefile \
$eventfiles \
$winfiles \
apache/GNUmakefile apache/httpd.conf \
......
......@@ -11,7 +11,7 @@ SUBDIR = tools
include $(OBJDIR)/Makeconf
SUBDIRS = pcapper teachswitch webcamapplet
SUBDIRS = pcapper teachswitch webcamapplet whol
all: all-subdirs
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# All rights reserved.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ../..
SUBDIR = tools/whol
include $(OBJDIR)/Makeconf
all: whol
include $(TESTBED_SRCDIR)/GNUmakerules
whol: GNUmakefile whol.o
$(CC) $(CFLAGS) $(LDFLAGS) whol.o -o whol
cp whol whol.debug
strip whol
whol.o: whol.c
$(CC) -c -o whol.o $(CFLAGS) $<
install: $(INSTALL_SBINDIR)/whol
clean:
rm -f *.o core whol whol.debug
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2005 University of Utah and the Flux Group.
*
* whol.c - Send a 'whack on LAN' packet to node
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
u_short in_cksum(u_short *addr, int len);
const int MAX_BPFNUM = 16;
const int packet_len = 666;
int main(int argc, char **argv) {
int bpfnum;
int bpffd;
struct ifreq req;
void *buf;
ssize_t written;
int i,j,length;
struct ether_header *eheader;
struct ip *ip;
struct udphdr *udp;
char *pbody;
char *victim;
char *iface;
u_char dst_mac[6];
/*
* Handle command line args
*/
if (argc != 3) {
fprintf(stderr,"Usage: whol <dst_address> <interface>\n");
fprintf(stderr,"dst_addr: A MAC address in hex, without puncuation\n");
fprintf(stderr,"interface: Name of the interface to send packet on\n");
exit(1);
}
victim = argv[1];
iface = argv[2];
/*
* Convert the victim MAC address from ASCII into bytes
*/
if (strlen(victim) != 12) {
fprintf(stderr,"Bad format for MAC address\n");
exit(1);
}
for (i = 0; i < 6; i++) {
char digits[3];
unsigned int tmp;
strncpy(digits, victim + (i*2),3); /* Copy in two digits */
digits[2] = '\0'; /* Null-terminate */
if (sscanf(digits,"%x",&tmp) != 1) {
printf("Bad hex value in dst_addr: %s\n",digits);
exit(1);
}
dst_mac[i] = tmp;
}
/*
* Find and open a BPF device to send the packet on
*/
for (bpfnum = 0; bpfnum < MAX_BPFNUM; bpfnum++) {
char bpfpath[1024];
sprintf(bpfpath,"/dev/bpf%i",bpfnum);
bpffd = open(bpfpath,O_WRONLY);
if (bpffd >= 0) {
break;
}
}
if (bpffd < 0) {
fprintf(stderr,"Failed to find an open-able BPF device\n");
exit(1);
}
/*
* Attach it to the correct interface
*/
strcpy(req.ifr_name,iface);
if (ioctl(bpffd,BIOCSETIF,&req) < 0) {
perror("BIOSETIF failed");
exit(1);
}
/*
* Build up a packet ourselves
*/
buf = (void*)malloc(packet_len);
bzero(buf,packet_len);
eheader = buf;
ip = buf + ETHER_HDR_LEN;
udp = buf + ETHER_HDR_LEN + sizeof(*ip);
pbody = buf + ETHER_HDR_LEN + sizeof(*ip) + sizeof(*udp);
/*
* Fill in the destination MAC, and make it look like an IP packet so that
* the switch will deliver it.
*/
for (i = 0; i < ETHER_ADDR_LEN; i++) {
eheader->ether_dhost[i] = dst_mac[i];
}
eheader->ether_type = htons(ETHERTYPE_IP);
/* Note: The NIC will fill in the src MAC automagically */
/*
* Make an IP header
*/
ip->ip_hl = (sizeof *ip >> 2);
ip->ip_v = 4;
ip->ip_tos = 0;
ip->ip_len = htons(packet_len - ETHER_HDR_LEN);
ip->ip_id = 0;
ip->ip_off = 0;
ip->ip_ttl = 1;
ip->ip_p = 17; /* UDP, really oughta use getprotobyname */
ip->ip_src.s_addr = 0xffffffff;
ip->ip_dst.s_addr = 0xffffffff;
ip->ip_sum = in_cksum((u_short *)ip,sizeof(*ip));
/*
* Make a UDP header
*/
udp->uh_sport = 0;
udp->uh_dport = 0;
udp->uh_ulen = htons(packet_len - ETHER_HDR_LEN - sizeof(*ip) - sizeof(*udp));
udp->uh_sum = 0;
/*
* Put in the magic juice that maekes the victim reboot - 6 bytes of 1s,
* then 16 repititions of the victim's MAC address
*/
length = 0;
for (i = 0; i < 6; i++) {
pbody[length++] = (char)0xff;
}
for (i = 0; i < 16; i++) {
for (j = 0; j < 6; j++) {
pbody[length++] = dst_mac[j];
}
}
/*
* Whack away!
*/
printf("Whack!\n");
written = write(bpffd,buf,packet_len);
if (written < 0) {
perror("Write failed");
}
exit(0);
}
/*
* in_cksum --
* Checksum routine for Internet Protocol family headers (C Version)
* From FreeBSD's ping.c
*/
u_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;
/*
* 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) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
/* 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 */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment