/* Called only from main, once */ static int arp_set(char **args) { char *host; struct arpreq req; struct sockaddr sa; int flags; memset(&req, 0, sizeof(req)); host = *args++; if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } /* If a host has more than one address, use the correct one! */ memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr)); /* Fetch the hardware address. */ if (*args == NULL) { bb_error_msg_and_die("need hardware address"); } if (option_mask32 & ARP_OPT_D) { arp_getdevhw(*args++, &req.arp_ha, hw_set ? hw : NULL); } else { if (hw->input(*args++, &req.arp_ha) < 0) { bb_error_msg_and_die("invalid hardware address"); } } /* Check out any modifiers. */ flags = ATF_PERM | ATF_COM; while (*args != NULL) { switch (index_in_strings(options, *args)) { case 0: /* "pub" */ flags |= ATF_PUBL; args++; break; case 1: /* "priv" */ flags &= ~ATF_PUBL; args++; break; case 2: /* "temp" */ flags &= ~ATF_PERM; args++; break; case 3: /* "trail" */ flags |= ATF_USETRAILERS; args++; break; case 4: /* "dontpub" */ #ifdef HAVE_ATF_DONTPUB flags |= ATF_DONTPUB; #else bb_error_msg("feature ATF_DONTPUB is not supported"); #endif args++; break; case 5: /* "auto" */ #ifdef HAVE_ATF_MAGIC flags |= ATF_MAGIC; #else bb_error_msg("feature ATF_MAGIC is not supported"); #endif args++; break; case 6: /* "dev" */ if (*++args == NULL) bb_show_usage(); device = *args; args++; break; case 7: /* "netmask" */ if (*++args == NULL) bb_show_usage(); if (strcmp(*args, "255.255.255.255") != 0) { host = *args; if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr)); flags |= ATF_NETMASK; } args++; break; default: bb_show_usage(); break; } } /* Fill in the remainder of the request. */ req.arp_flags = flags; strncpy(req.arp_dev, device, sizeof(req.arp_dev)); /* Call the kernel. */ if (option_mask32 & ARP_OPT_v) bb_error_msg("SIOCSARP()"); xioctl(sockfd, SIOCSARP, &req); return 0; }
/* Set an entry in the ARP cache. */ static int arp_set(char **args) { char host[128]; struct arpreq req; struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; int flags; memset((char *) &req, 0, sizeof(req)); /* Resolve the host name. */ if (*args == NULL) { fprintf(stderr, _("arp: need host name\n")); return (-1); } safe_strncpy(host, *args++, (sizeof host)); if (ap->input(0, host, &ss) < 0) { ap->herror(host); return (-1); } /* If a host has more than one address, use the correct one! */ memcpy((char *) &req.arp_pa, (char *) sa, sizeof(struct sockaddr)); /* Fetch the hardware address. */ if (*args == NULL) { fprintf(stderr, _("arp: need hardware address\n")); return (-1); } if (opt_D) { if (arp_getdevhw(*args++, &req.arp_ha, hw_set ? hw : NULL) < 0) return (-1); } else { if (hw->input(*args++, &ss) < 0) { fprintf(stderr, _("arp: invalid hardware address\n")); return (-1); } memcpy(&req.arp_ha, sa, sizeof(*sa)); } /* Check out any modifiers. */ flags = ATF_PERM | ATF_COM; while (*args != NULL) { if (!strcmp(*args, "temp")) { flags &= ~ATF_PERM; args++; continue; } if (!strcmp(*args, "pub")) { flags |= ATF_PUBL; args++; continue; } if (!strcmp(*args, "priv")) { flags &= ~ATF_PUBL; args++; continue; } if (!strcmp(*args, "trail")) { flags |= ATF_USETRAILERS; args++; continue; } if (!strcmp(*args, "dontpub")) { #ifdef ATF_DONTPUB flags |= ATF_DONTPUB; #else ENOSUPP("arp", "ATF_DONTPUB"); #endif args++; continue; } if (!strcmp(*args, "auto")) { #ifdef ATF_MAGIC flags |= ATF_MAGIC; #else ENOSUPP("arp", "ATF_MAGIC"); #endif args++; continue; } if (!strcmp(*args, "dev")) { if (*++args == NULL) usage(); safe_strncpy(device, *args, sizeof(device)); args++; continue; } if (!strcmp(*args, "netmask")) { if (*++args == NULL) usage(); if (strcmp(*args, "255.255.255.255") != 0) { safe_strncpy(host, *args, (sizeof host)); if (ap->input(0, host, &ss) < 0) { ap->herror(host); return (-1); } memcpy((char *) &req.arp_netmask, (char *) sa, sizeof(struct sockaddr)); flags |= ATF_NETMASK; } args++; continue; } usage(); } /* Fill in the remainder of the request. */ req.arp_flags = flags; safe_strncpy(req.arp_dev, device, sizeof(req.arp_dev)); /* Call the kernel. */ if (opt_v) fprintf(stderr, "arp: SIOCSARP()\n"); if (ioctl(sockfd, SIOCSARP, &req) < 0) { perror("SIOCSARP"); return (-1); } return (0); }
/* Set an entry in the ARP cache. */ static int arp_set(char **args) { char host[128]; struct arpreq req; struct sockaddr sa; int flags; memset((char *) &req, 0, sizeof(req)); /* Resolve the host name. */ if (*args == NULL) { bb_error_msg("need host name\n"); return -1; } safe_strncpy(host, *args++, (sizeof host)); if (ap->input(0, host, &sa) < 0) { bb_herror_msg("%s", host); return -1; } /* If a host has more than one address, use the correct one! */ memcpy((char *) &req.arp_pa, (char *) &sa, sizeof(struct sockaddr)); /* Fetch the hardware address. */ if (*args == NULL) { bb_error_msg("need hardware address\n"); return -1; } if (opt_D) { if (arp_getdevhw(*args++, &req.arp_ha, hw_set ? hw : NULL) < 0) return (-1); } else { if (hw->input(*args++, &req.arp_ha) < 0) { bb_error_msg("invalid hardware address\n"); return -1; } } /* Check out any modifiers. */ flags = ATF_PERM | ATF_COM; while (*args != NULL) { if (!strcmp(*args, "temp")) { flags &= ~ATF_PERM; args++; continue; } if (!strcmp(*args, "pub")) { flags |= ATF_PUBL; args++; continue; } if (!strcmp(*args, "priv")) { flags &= ~ATF_PUBL; args++; continue; } if (!strcmp(*args, "trail")) { flags |= ATF_USETRAILERS; args++; continue; } if (!strcmp(*args, "dontpub")) { #ifdef HAVE_ATF_DONTPUB flags |= ATF_DONTPUB; #else bb_error_msg("feature ATF_DONTPUB is not supported"); #endif args++; continue; } if (!strcmp(*args, "auto")) { #ifdef HAVE_ATF_MAGIC flags |= ATF_MAGIC; #else bb_error_msg("feature ATF_MAGIC is not supported"); #endif args++; continue; } if (!strcmp(*args, "dev")) { if (*++args == NULL) bb_show_usage(); safe_strncpy(device, *args, sizeof(device)); args++; continue; } if (!strcmp(*args, "netmask")) { if (*++args == NULL) bb_show_usage(); if (strcmp(*args, "255.255.255.255") != 0) { strcpy(host, *args); if (ap->input(0, host, &sa) < 0) { bb_herror_msg("%s", host); return (-1); } memcpy((char *) &req.arp_netmask, (char *) &sa, sizeof(struct sockaddr)); flags |= ATF_NETMASK; } args++; continue; } bb_show_usage(); } /* Fill in the remainder of the request. */ req.arp_flags = flags; strcpy(req.arp_dev, device); /* Call the kernel. */ if (opt_v) bb_error_msg("SIOCSARP()\n"); if (ioctl(sockfd, SIOCSARP, &req) < 0) { perror("SIOCSARP"); return -1; } return 0; }