/*
* arp.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: arp.c,v 1.10 2002/05/08 04:55:32 dugsong Exp $
*/
#include "config.h"
#include <sys/types.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "dnet.h"
#include "aton.h"
#include "mod.h"
void
arp_usage(void)
{
fprintf(stderr, "Usage: dnet arp [op|sha|spa|tha|tpa <value>] ...\n"
" dnet arp show\n"
" dnet arp get <host>\n"
" dnet arp add <host> <mac>\n"
" dnet arp delete <host>\n");
exit(1);
}
static int
print_arp(const struct arp_entry *entry, void *arg)
{
printf("%s at %s\n", addr_ntoa(&entry->arp_pa),
addr_ntoa(&entry->arp_ha));
return (0);
}
static int
arp_kern_main(int argc, char *argv[])
{
struct arp_entry entry;
arp_t *arp;
char *cmd;
if (argc < 2)
arp_usage();
cmd = argv[1];
if ((arp = arp_open()) == NULL)
err(1, "arp_open");
if (strcmp(cmd, "show") == 0) {
if (arp_loop(arp, print_arp, NULL) < 0)
err(1, "arp_loop");
} else if (strcmp(cmd, "get") == 0) {
if (addr_pton(argv[2], &entry.arp_pa) < 0)
err(1, "addr_pton");
if (arp_get(arp, &entry) < 0)
err(1, "arp_get");
print_arp(&entry, NULL);
} else if (strcmp(cmd, "add") == 0) {
if (addr_pton(argv[2], &entry.arp_pa) < 0 ||
addr_pton(argv[3], &entry.arp_ha) < 0)
err(1, "addr_pton");
if (arp_add(arp, &entry) < 0)
err(1, "arp_add");
printf("%s added\n", addr_ntoa(&entry.arp_pa));
} else if (strcmp(cmd, "delete") == 0) {
if (addr_pton(argv[2], &entry.arp_pa) < 0)
err(1, "addr_pton");
if (arp_delete(arp, &entry) < 0)
err(1, "arp_delete");
printf("%s deleted\n", addr_ntoa(&entry.arp_pa));
} else
arp_usage();
arp_close(arp);
return (0);
}
int
arp_main(int argc, char *argv[])
{
struct arp_hdr *arp;
struct arp_ethip *ethip;
struct addr addr;
u_char *p, buf[ETH_MTU]; /* XXX */
char *name, *value;
int c, len;
if (argc == 1 || *(argv[1]) == '-')
arp_usage();
/* XXX - total trash */
if (argc > 1 &&
(strcmp(argv[1], "show") == 0 || strcmp(argv[1], "get") == 0 ||
strcmp(argv[1], "add") == 0 || strcmp(argv[1], "delete") == 0))
return (arp_kern_main(argc, argv));
srand(time(NULL));
arp = (struct arp_hdr *)buf;
arp->ar_hrd = htons(ARP_HRD_ETH);
arp->ar_pro = htons(ARP_PRO_IP);
arp->ar_hln = ETH_ADDR_LEN;
arp->ar_pln = IP_ADDR_LEN;
arp->ar_op = ARP_OP_REQUEST;
ethip = (struct arp_ethip *)(buf + ARP_HDR_LEN);
memset(ethip, 0, sizeof(*ethip));
for (c = 1; c + 1 < argc; c += 2) {
name = argv[c];
value = argv[c + 1];
if (strcmp(name, "op") == 0) {
if (op_aton(value, &arp->ar_op) < 0)
arp_usage();
} else if (strcmp(name, "sha") == 0) {
if (addr_aton(value, &addr) < 0)
arp_usage();
memcpy(ethip->ar_sha, &addr.addr_eth, ETH_ADDR_LEN);
} else if (strcmp(name, "spa") == 0) {
if (addr_aton(value, &addr) < 0)
arp_usage();
memcpy(ethip->ar_spa, &addr.addr_ip, IP_ADDR_LEN);
} else if (strcmp(name, "tha") == 0) {
if (addr_aton(value, &addr) < 0)
arp_usage();
memcpy(ethip->ar_tha, &addr.addr_eth, ETH_ADDR_LEN);
} else if (strcmp(name, "tpa") == 0) {
if (addr_aton(value, &addr) < 0)
arp_usage();
memcpy(ethip->ar_tpa, &addr.addr_ip, IP_ADDR_LEN);
}
else
arp_usage();
}
argc -= c;
argv += c;
if (argc != 0)
arp_usage();
p = buf + ARP_HDR_LEN + ARP_ETHIP_LEN;
if (!isatty(STDIN_FILENO)) {
len = sizeof(buf) - (p - buf);
while ((c = read(STDIN_FILENO, p, len)) > 0) {
p += c;
len -= c;
}
}
len = p - buf;
if (write(STDOUT_FILENO, buf, len) != len)
err(1, "write");
return (0);
}
struct mod mod_arp = {
"arp",
MOD_TYPE_ENCAP|MOD_TYPE_KERN,
arp_main
};
syntax highlighted by Code2HTML, v. 0.9.1