/* * Display an individual arp entry */ static void get(const char *host) { struct sockaddr_inarp sin = blank_sin; /* struct copy */ if (getinetaddr(host, &sin.sin_addr) == -1) exit(1); dump(sin.sin_addr.s_addr); if (found_entry == 0) errx(1, "%s (%s) -- no entry", host, inet_ntoa(sin.sin_addr)); }
/* * Display an individual arp entry */ int get(const char *host) { struct sockaddr_inarp *sin; sin = &sin_m; sin_m = blank_sin; /* struct copy */ if (getinetaddr(host, &sin->sin_addr) == -1) exit(1); search(sin->sin_addr.s_addr, print_entry); if (found_entry == 0) { printf("%s (%s) -- no entry\n", host, inet_ntoa(sin->sin_addr)); return (1); } return (0); }
/* * Display an individual arp entry */ int get(const char *host) { struct sockaddr_inarp *sin; sin = &sin_m; sin_m = blank_sin; /* struct copy */ if (getinetaddr(host, &sin->sin_addr) == -1) exit(1); printf("%-*.*s %-*.*s %*.*s %-10.10s %5s\n", W_ADDR, W_ADDR, "Host", W_LL, W_LL, "Ethernet Address", W_IF, W_IF, "Netif", "Expire", "Flags"); search(sin->sin_addr.s_addr, print_entry); if (found_entry == 0) { printf("%-*.*s no entry\n", W_ADDR, W_ADDR, inet_ntoa(sin->sin_addr)); return (1); } return (0); }
/* * Set an individual arp entry */ int set(int argc, char *argv[]) { struct sockaddr_inarp *sin; struct sockaddr_dl *sdl; struct rt_msghdr *rtm; char *eaddr = argv[1], *host = argv[0]; struct ether_addr *ea; sin = &sin_m; rtm = &(m_rtmsg.m_rtm); getsocket(); argc -= 2; argv += 2; sdl_m = blank_sdl; /* struct copy */ sin_m = blank_sin; /* struct copy */ if (getinetaddr(host, &sin->sin_addr) == -1) return (1); ea = ether_aton(eaddr); if (ea == NULL) errx(1, "invalid ethernet address: %s", eaddr); memcpy(LLADDR(&sdl_m), ea, sizeof(*ea)); sdl_m.sdl_alen = 6; expire_time = 0; doing_proxy = flags = export_only = 0; while (argc-- > 0) { if (strncmp(argv[0], "temp", 4) == 0) { struct timeval now; gettimeofday(&now, 0); expire_time = now.tv_sec + 20 * 60; if (flags & RTF_PERMANENT_ARP) { /* temp or permanent, not both */ usage(); return (0); } } else if (strncmp(argv[0], "pub", 3) == 0) { flags |= RTF_ANNOUNCE; doing_proxy = SIN_PROXY; } else if (strncmp(argv[0], "permanent", 9) == 0) { flags |= RTF_PERMANENT_ARP; if (expire_time != 0) { /* temp or permanent, not both */ usage(); return (0); } } argv++; } tryagain: if (rtget(&sin, &sdl)) { warn("%s", host); return (1); } if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) { if (sdl->sdl_family == AF_LINK && (rtm->rtm_flags & RTF_LLINFO) && !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: case IFT_ISO88024: case IFT_ISO88025: case IFT_CARP: goto overwrite; } if (doing_proxy == 0) { printf("set: can only proxy for %s\n", host); return (1); } if (sin_m.sin_other & SIN_PROXY) { printf("set: proxy entry exists for non 802 device\n"); return (1); } sin_m.sin_other = SIN_PROXY; export_only = 1; goto tryagain; } overwrite: if (sdl->sdl_family != AF_LINK) { printf("cannot intuit interface index and type for %s\n", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return (rtmsg(RTM_ADD)); }
/* * Set an individual arp entry */ static int set(int argc, char **argv) { struct sockaddr_inarp *sina; struct sockaddr_dl *sdl; struct rt_msghdr *rtm; char *host = argv[0], *eaddr; struct sockaddr_inarp sin_m = blank_sin; /* struct copy */ struct sockaddr_dl sdl_m = blank_sdl; /* struct copy */ int s; eaddr = argv[1]; s = getsocket(); argc -= 2; argv += 2; if (getinetaddr(host, &sin_m.sin_addr) == -1) return (1); if (atosdl(eaddr, &sdl_m)) warnx("invalid link-level address '%s'", eaddr); doing_proxy = flags = export_only = expire_time = 0; for (; argc-- > 0; argv++) { if (strncmp(argv[0], "temp", 4) == 0) { struct timeval timev; (void)gettimeofday(&timev, 0); expire_time = timev.tv_sec + 20 * 60; } else if (strncmp(argv[0], "pub", 3) == 0) { flags |= RTF_ANNOUNCE; doing_proxy = SIN_PROXY; if (argc && strncmp(argv[1], "pro", 3) == 0) { export_only = 1; argc--; argv++; } } else if (strncmp(argv[0], "trail", 5) == 0) { warnx("%s: Sending trailers is no longer supported", host); } else if (strcmp(argv[0], "ifscope") == 0) { if (argc == 0) { warnx("missing interface for ifscope"); continue; } argc--; argv++; if (!getlink(argv[0], &sdl_m)) warnx("cannot get link address for %s", argv[0]); } } if (memcmp(&sdl_m, &blank_sdl, sizeof(blank_sdl))) goto out; tryagain: rtm = rtmsg(s, RTM_GET, &sin_m, &sdl_m); if (rtm == NULL) { warn("%s", host); return (1); } sina = (struct sockaddr_inarp *)(void *)(rtm + 1); sdl = (struct sockaddr_dl *)(void *)(RT_ROUNDUP(sina->sin_len) + (char *)(void *)sina); if (sina->sin_addr.s_addr == sin_m.sin_addr.s_addr) { if (is_llinfo(sdl, rtm->rtm_flags)) goto overwrite; if (doing_proxy == 0) { warnx("set: can only proxy for %s", host); return (1); } if (sin_m.sin_other & SIN_PROXY) { warnx("set: proxy entry exists for non 802 device"); return (1); } sin_m.sin_other = SIN_PROXY; export_only = 1; goto tryagain; } overwrite: if (sdl->sdl_family != AF_LINK) { warnx("cannot intuit interface index and type for %s", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; out: sin_m.sin_other = 0; if (doing_proxy && export_only) sin_m.sin_other = SIN_PROXY; rtm = rtmsg(s, RTM_ADD, &sin_m, &sdl_m); if (vflag) (void)printf("%s (%s) added\n", host, eaddr); return (rtm == NULL) ? 1 : 0; }