00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "config.h"
00010
00011 #include <sys/types.h>
00012
00013 #include <err.h>
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <time.h>
00018 #include <unistd.h>
00019
00020 #include "dnet.h"
00021 #include "aton.h"
00022 #include "mod.h"
00023
00024 void
00025 arp_usage(void)
00026 {
00027 fprintf(stderr, "Usage: dnet arp [op|sha|spa|tha|tpa <value>] ...\n"
00028 " dnet arp show\n"
00029 " dnet arp get <host>\n"
00030 " dnet arp add <host> <mac>\n"
00031 " dnet arp delete <host>\n");
00032 exit(1);
00033 }
00034
00035 static int
00036 print_arp(const struct arp_entry *entry, void *arg)
00037 {
00038 printf("%s at %s\n", addr_ntoa(&entry->arp_pa),
00039 addr_ntoa(&entry->arp_ha));
00040 return (0);
00041 }
00042
00043 static int
00044 arp_kern_main(int argc, char *argv[])
00045 {
00046 struct arp_entry entry;
00047 arp_t *arp;
00048 char *cmd;
00049
00050 if (argc < 2)
00051 arp_usage();
00052
00053 cmd = argv[1];
00054
00055 if ((arp = arp_open()) == NULL)
00056 err(1, "arp_open");
00057
00058 if (strcmp(cmd, "show") == 0) {
00059 if (arp_loop(arp, print_arp, NULL) < 0)
00060 err(1, "arp_loop");
00061 } else if (strcmp(cmd, "get") == 0) {
00062 if (addr_pton(argv[2], &entry.arp_pa) < 0)
00063 err(1, "addr_pton");
00064 if (arp_get(arp, &entry) < 0)
00065 err(1, "arp_get");
00066 print_arp(&entry, NULL);
00067 } else if (strcmp(cmd, "add") == 0) {
00068 if (addr_pton(argv[2], &entry.arp_pa) < 0 ||
00069 addr_pton(argv[3], &entry.arp_ha) < 0)
00070 err(1, "addr_pton");
00071 if (arp_add(arp, &entry) < 0)
00072 err(1, "arp_add");
00073 printf("%s added\n", addr_ntoa(&entry.arp_pa));
00074 } else if (strcmp(cmd, "delete") == 0) {
00075 if (addr_pton(argv[2], &entry.arp_pa) < 0)
00076 err(1, "addr_pton");
00077 if (arp_delete(arp, &entry) < 0)
00078 err(1, "arp_delete");
00079 printf("%s deleted\n", addr_ntoa(&entry.arp_pa));
00080 } else
00081 arp_usage();
00082
00083 arp_close(arp);
00084
00085 return (0);
00086 }
00087
00088 int
00089 arp_main(int argc, char *argv[])
00090 {
00091 struct arp_hdr *arp;
00092 struct arp_ethip *ethip;
00093 struct addr addr;
00094 u_char *p, buf[ETH_MTU];
00095 char *name, *value;
00096 int c, len;
00097
00098 if (argc == 1 || *(argv[1]) == '-')
00099 arp_usage();
00100
00101
00102 if (argc > 1 &&
00103 (strcmp(argv[1], "show") == 0 || strcmp(argv[1], "get") == 0 ||
00104 strcmp(argv[1], "add") == 0 || strcmp(argv[1], "delete") == 0))
00105 return (arp_kern_main(argc, argv));
00106
00107 srand(time(NULL));
00108
00109 arp = (struct arp_hdr *)buf;
00110 arp->ar_hrd = htons(ARP_HRD_ETH);
00111 arp->ar_pro = htons(ARP_PRO_IP);
00112 arp->ar_hln = ETH_ADDR_LEN;
00113 arp->ar_pln = IP_ADDR_LEN;
00114 arp->ar_op = ARP_OP_REQUEST;
00115
00116 ethip = (struct arp_ethip *)(buf + ARP_HDR_LEN);
00117 memset(ethip, 0, sizeof(*ethip));
00118
00119 for (c = 1; c + 1 < argc; c += 2) {
00120 name = argv[c];
00121 value = argv[c + 1];
00122
00123 if (strcmp(name, "op") == 0) {
00124 if (op_aton(value, &arp->ar_op) < 0)
00125 arp_usage();
00126 } else if (strcmp(name, "sha") == 0) {
00127 if (addr_aton(value, &addr) < 0)
00128 arp_usage();
00129 memcpy(ethip->ar_sha, &addr.addr_eth, ETH_ADDR_LEN);
00130 } else if (strcmp(name, "spa") == 0) {
00131 if (addr_aton(value, &addr) < 0)
00132 arp_usage();
00133 memcpy(ethip->ar_spa, &addr.addr_ip, IP_ADDR_LEN);
00134 } else if (strcmp(name, "tha") == 0) {
00135 if (addr_aton(value, &addr) < 0)
00136 arp_usage();
00137 memcpy(ethip->ar_tha, &addr.addr_eth, ETH_ADDR_LEN);
00138 } else if (strcmp(name, "tpa") == 0) {
00139 if (addr_aton(value, &addr) < 0)
00140 arp_usage();
00141 memcpy(ethip->ar_tpa, &addr.addr_ip, IP_ADDR_LEN);
00142 }
00143 else
00144 arp_usage();
00145 }
00146 argc -= c;
00147 argv += c;
00148
00149 if (argc != 0)
00150 arp_usage();
00151
00152 p = buf + ARP_HDR_LEN + ARP_ETHIP_LEN;
00153
00154 if (!isatty(STDIN_FILENO)) {
00155 len = sizeof(buf) - (p - buf);
00156 while ((c = read(STDIN_FILENO, p, len)) > 0) {
00157 p += c;
00158 len -= c;
00159 }
00160 }
00161 len = p - buf;
00162
00163 if (write(STDOUT_FILENO, buf, len) != len)
00164 err(1, "write");
00165
00166 return (0);
00167 }
00168
00169 struct mod mod_arp = {
00170 "arp",
00171 MOD_TYPE_ENCAP|MOD_TYPE_KERN,
00172 arp_main
00173 };