/****************************************************************************
Program: $Id: dnetspoof.c,v 1.2 2006/11/19 21:01:17 rbeverly Exp $
Author: Rob Beverly <rbeverly@mit.edu>
Date: $Date: 2006/11/19 21:01:17 $
Description: Spoofer utility routines
****************************************************************************/
#include "spoof.h"
#ifdef _WIN32
#include "dnet.h"
#define INT_NAME_LEN 10
#define MAX_INTERFACES 10
static char intlist[INT_NAME_LEN * MAX_INTERFACES];
static int intcount = 0;
static int intselected = 0;
static struct eth_hdr eh;
static eth_t *e = NULL;
int etherOpen(char *dev) {
if (e != NULL)
return(-1);
if ((e = eth_open(dev)) == NULL) {
printf("err: eth_open: %s\n", dev);
return(-1);
}
return(0);
}
int etherClose() {
if (e == NULL)
return(-1);
e = NULL;
return(0);
}
void print_eth(eth_addr_t *ea) {
uint8_t *u;
int i;
u = (uint8_t *)ea;
for (i=0;i<ETH_ADDR_LEN;i++) {
if (DEBUG) printf("Byte[%d]: %02x\n", i, *u);
printf("%02x", *u);
if (i < ETH_ADDR_LEN-1) printf(":");
u++;
}
printf("\n");
}
struct addr getRoute(char *dst) {
route_t *r;
struct route_entry re;
memset(&re, 0, sizeof(struct route_entry));
if ((r = route_open()) == NULL)
printf("err: route_open()\n");
re.route_dst.addr_ip = inet_addr(dst);
re.route_dst.addr_type = ADDR_TYPE_IP;
re.route_dst.addr_bits = IP_ADDR_BITS;
if (route_get(r, &re) < 0)
if (DEBUG) printf("err: route_get()\n");
route_close(r);
return (re.route_gw);
}
struct addr getARP(struct addr *pa) {
arp_t *a;
struct arp_entry ae;
memset(&ae, 0, sizeof(struct arp_entry));
if ((a = arp_open()) == NULL)
printf("err: arp_open()\n");
ae.arp_pa = *pa;
if (arp_get(a, &ae) < 0)
printf("err: arp_get()\n");
arp_close(a);
return (ae.arp_ha);
}
int grabEther(struct eth_hdr *eh) {
eth_addr_t ea;
struct addr gw;
struct addr gw_eth;
memset(&gw, 0, sizeof(struct addr));
memset(&gw_eth, 0, sizeof(struct addr));
printf(">> Fetching MAC address of %s...", &intlist[intselected*INT_NAME_LEN]);
eth_get(e, &ea);
print_eth(&ea);
if (DEBUG) printf(">> Fetching route toward: %s...", SERVER);
gw = getRoute(SERVER);
/* if no route found, server may be local, so arp for server */
if (gw.addr_ip == 0) {
gw.addr_ip = inet_addr(SERVER);
gw.addr_type = ADDR_TYPE_IP;
gw.addr_bits = IP_ADDR_BITS;
}
if (DEBUG) printf("%d.%d.%d.%d\n", NIPQUAD(gw.addr_ip));
printf(">> Fetching arp entry for %d.%d.%d.%d...", NIPQUAD(gw.addr_ip));
gw_eth = getARP(&gw);
if (gw_eth.addr_type == ADDR_TYPE_NONE) {
fatal("\n*** FATAL: Couldn't determine destination MAC address. Bailing.\n");
}
print_eth(&gw_eth.addr_eth);
eh->eth_type = htons(ETH_TYPE_IP);
memcpy(&eh->eth_src, &ea, ETH_ADDR_LEN);
memcpy(&eh->eth_dst, &gw_eth.addr_eth, ETH_ADDR_LEN);
eth_close(e);
return(0);
}
static int print_intf(const struct intf_entry *entry, void *ar) {
char *p;
/* skip loopback */
if (strstr(entry->intf_name, "lo") != NULL)
return(0);
/* skip ppp */
if (strstr(entry->intf_name, "ppp") != NULL)
return(0);
/* skip slip */
if (strstr(entry->intf_name, "slip") != NULL)
return(0);
/* only consider numbered interfaces */
if (entry->intf_addr.addr_type != ADDR_TYPE_IP)
return(0);
/* only consider up interfaces */
if (entry->intf_flags & INTF_FLAG_UP) {
if (DEBUG) printf("%s:\n", entry->intf_name);
p = &intlist[intcount*INT_NAME_LEN];
snprintf(p, INT_NAME_LEN, "%s", entry->intf_name);
intcount++;
}
return(0);
}
int findInterfaces() {
static intf_t *intf;
if ((intf = intf_open()) == NULL) {
printf("err: intf_open()\n");
return(-1);
}
if (intf_loop(intf, print_intf, NULL) < 0) {
printf("err: intf_loop()\n");
return(-1);
}
intf_close(intf);
return(intcount);
}
void selectInterface() {
int i;
int input=0;
for (i=0;i<intcount;i++) {
printf("IP Interface[%d]: %s\n", i, &intlist[i*INT_NAME_LEN]);
}
while ( (input < 48) || (input > (47 + intcount)) ) {
printf("\nSelect Interface [0-%d]>", intcount-1);
input = getchar();
}
printf("Selected Interface: [%s]\n", &intlist[(input-48)*INT_NAME_LEN]);
intselected = input-48;
}
int registerEther() {
memset(&eh, 0, sizeof(struct eth_hdr));
etherOpen(&intlist[intselected*INT_NAME_LEN]);
grabEther(&eh);
if (DEBUG) {
printf("registerEther()\n");
print_eth(&eh.eth_src);
print_eth(&eh.eth_dst);
}
return(0);
}
int deregisterEther() {
memset(&eh, 0, sizeof(struct eth_hdr));
intcount = intselected = 0;
etherClose();
return(0);
}
int etherSend(void *msg, int len) {
char buf[BUFSIZE];
int packetlen = 0;
int ret = 0;
packetlen = ETH_HDR_LEN + len;
if (packetlen > BUFSIZE)
return(-1);
/* RB: Unclear why I have to close and reopen each time. Fix later */
etherClose();
etherOpen(&intlist[intselected*INT_NAME_LEN]);
eh.eth_type = htons(ETH_TYPE_IP);
memcpy(&buf[0], &eh, sizeof(struct eth_hdr));
memcpy(&buf[ETH_HDR_LEN], msg, len);
ip_checksum(&buf[ETH_HDR_LEN], len);
if ((ret = eth_send(e, buf, packetlen)) != packetlen)
printf("err: eth_send\n");
if (DEBUG) printf("Sent %d bytes\n", ret);
return(ret);
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1