/* * arp.c * * Copyright (c) 2001 Dug Song * * $Id: arp.c,v 1.10 2002/05/08 04:55:32 dugsong Exp $ */ #include "config.h" #include #include #include #include #include #include #include #include "dnet.h" #include "aton.h" #include "mod.h" void arp_usage(void) { fprintf(stderr, "Usage: dnet arp [op|sha|spa|tha|tpa ] ...\n" " dnet arp show\n" " dnet arp get \n" " dnet arp add \n" " dnet arp delete \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 };