* NET-3 Networking Distribution for the LINUX operating
* system.
*
- * Version: $Id: arp.c,v 1.21 2001/05/06 02:14:07 ecki Exp $
+ * Version: $Id: arp.c,v 1.27 2009/09/06 22:50:11 vapier Exp $
*
* Maintainer: Bernd 'eckes' Eckenfels, <net-tools@lina.inka.de>
*
{
char host[128];
struct arpreq req;
- struct sockaddr sa;
+ struct sockaddr_storage ss;
+ struct sockaddr *sa;
int flags = 0;
- int err;
+ int deleted = 0;
memset((char *) &req, 0, sizeof(req));
return (-1);
}
safe_strncpy(host, *args, (sizeof host));
- if (ap->input(0, host, &sa) < 0) {
+ sa = (struct sockaddr *)&ss;
+ if (ap->input(0, host, sa) < 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));
+ memcpy((char *) &req.arp_pa, (char *) sa, sizeof(struct sockaddr));
if (hw_set)
req.arp_ha.sa_family = hw->type;
continue;
}
if (!strcmp(*args, "dontpub")) {
-#ifdef HAVE_ATF_DONTPUB
+#ifdef ATF_DONTPUB
req.arp_flags |= ATF_DONTPUB;
#else
ENOSUPP("arp", "ATF_DONTPUB");
continue;
}
if (!strcmp(*args, "auto")) {
-#ifdef HAVE_ATF_MAGIC
+#ifdef ATF_MAGIC
req.arp_flags |= ATF_MAGIC;
#else
ENOSUPP("arp", "ATF_MAGIC");
usage();
if (strcmp(*args, "255.255.255.255") != 0) {
strcpy(host, *args);
- if (ap->input(0, host, &sa) < 0) {
+ if (ap->input(0, host, sa) < 0) {
ap->herror(host);
return (-1);
}
- memcpy((char *) &req.arp_netmask, (char *) &sa,
+ memcpy((char *) &req.arp_netmask, (char *) sa,
sizeof(struct sockaddr));
req.arp_flags |= ATF_NETMASK;
}
}
usage();
}
+
+ // if neighter priv nor pub is given, work on both
if (flags == 0)
flags = 3;
strcpy(req.arp_dev, device);
- err = -1;
+ /* unfortuatelly the kernel interface does not allow us to
+ delete private entries anlone, so we need this hack
+ to avoid "not found" errors if we try both. */
+ deleted = 0;
/* Call the kernel. */
if (flags & 2) {
if (opt_v)
- fprintf(stderr, "arp: SIOCDARP(nopub)\n");
- if ((err = ioctl(sockfd, SIOCDARP, &req) < 0)) {
- if (errno == ENXIO) {
+ fprintf(stderr, "arp: SIOCDARP(dontpub)\n");
+ if (ioctl(sockfd, SIOCDARP, &req) < 0) {
+ if ((errno == ENXIO) || (errno == ENOENT)) {
if (flags & 1)
- goto nopub;
+ goto dontpub;
printf(_("No ARP entry for %s\n"), host);
return (-1);
}
- perror("SIOCDARP(priv)");
+ perror("SIOCDARP(dontpub)");
return (-1);
- }
+ } else
+ deleted = 1;
}
- if ((flags & 1) && (err)) {
- nopub:
+ if (!deleted && (flags & 1)) {
+ dontpub:
req.arp_flags |= ATF_PUBL;
if (opt_v)
fprintf(stderr, "arp: SIOCDARP(pub)\n");
if (ioctl(sockfd, SIOCDARP, &req) < 0) {
- if (errno == ENXIO) {
+ if ((errno == ENXIO) || (errno == ENOENT)) {
printf(_("No ARP entry for %s\n"), host);
return (-1);
}
struct ifreq ifr;
struct hwtype *xhw;
- strcpy(ifr.ifr_name, ifname);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
fprintf(stderr, _("arp: cant get HW-Address for `%s': %s.\n"), ifname, strerror(errno));
return (-1);
{
char host[128];
struct arpreq req;
- struct sockaddr sa;
+ struct sockaddr_storage ss;
+ struct sockaddr *sa;
int flags;
memset((char *) &req, 0, sizeof(req));
return (-1);
}
safe_strncpy(host, *args++, (sizeof host));
- if (ap->input(0, host, &sa) < 0) {
+ sa = (struct sockaddr *)&ss;
+ if (ap->input(0, host, sa) < 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));
+ memcpy((char *) &req.arp_pa, (char *) sa, sizeof(struct sockaddr));
/* Fetch the hardware address. */
if (*args == NULL) {
continue;
}
if (!strcmp(*args, "dontpub")) {
-#ifdef HAVE_ATF_DONTPUB
+#ifdef ATF_DONTPUB
flags |= ATF_DONTPUB;
#else
ENOSUPP("arp", "ATF_DONTPUB");
continue;
}
if (!strcmp(*args, "auto")) {
-#ifdef HAVE_ATF_MAGIC
+#ifdef ATF_MAGIC
flags |= ATF_MAGIC;
#else
ENOSUPP("arp", "ATF_MAGIC");
usage();
if (strcmp(*args, "255.255.255.255") != 0) {
strcpy(host, *args);
- if (ap->input(0, host, &sa) < 0) {
+ if (ap->input(0, host, sa) < 0) {
ap->herror(host);
return (-1);
}
- memcpy((char *) &req.arp_netmask, (char *) &sa,
+ memcpy((char *) &req.arp_netmask, (char *) sa,
sizeof(struct sockaddr));
flags |= ATF_NETMASK;
}
/* Print the contents of an ARP request block. */
-static void arp_disp_2(char *name, int type, int arp_flags, char *hwa, char *mask, char *dev)
+static void arp_disp_2(const char *name, int type, int arp_flags, const char *hwa, const char *mask, const char *dev)
{
static int title = 0;
struct hwtype *xhw;
strcat(flags, "M");
if (arp_flags & ATF_PUBL)
strcat(flags, "P");
-#ifdef HAVE_ATF_MAGIC
+#ifdef ATF_MAGIC
if (arp_flags & ATF_MAGIC)
strcat(flags, "A");
#endif
-#ifdef HAVE_ATF_DONTPUB
+#ifdef ATF_DONTPUB
if (arp_flags & ATF_DONTPUB)
strcat(flags, "!");
#endif
if (!(arp_flags & ATF_COM)) {
if (arp_flags & ATF_PUBL)
- printf("%-8.8s%-20.20s", "*", "*");
+ printf("%-8.8s%-20.20s", "*", _("<from_interface>"));
else
printf("%-8.8s%-20.20s", "", _("(incomplete)"));
} else {
}
/* Print the contents of an ARP request block. */
-static void arp_disp(char *name, char *ip, int type, int arp_flags, char *hwa, char *mask, char *dev)
+static void arp_disp(const char *name, const char *ip, int type, int arp_flags, const char *hwa, const char *mask, const char *dev)
{
struct hwtype *xhw;
if (!(arp_flags & ATF_COM)) {
if (arp_flags & ATF_PUBL)
- printf("* ");
+ printf("<from_interface> ");
else
printf(_("<incomplete> "));
} else {
printf("PERM ");
if (arp_flags & ATF_PUBL)
printf("PUB ");
-#ifdef HAVE_ATF_MAGIC
+#ifdef ATF_MAGIC
if (arp_flags & ATF_MAGIC)
printf("AUTO ");
#endif
-#ifdef HAVE_ATF_DONTPUB
+#ifdef ATF_DONTPUB
if (arp_flags & ATF_DONTPUB)
printf("DONTPUB ");
#endif
static int arp_show(char *name)
{
char host[100];
- struct sockaddr sa;
+ struct sockaddr_storage ss;
+ struct sockaddr *sa;
char ip[100];
char hwa[100];
char mask[100];
char dev[100];
int type, flags;
FILE *fp;
- char *hostname;
+ const char *hostname;
int num, entries = 0, showed = 0;
host[0] = '\0';
+ sa = (struct sockaddr *)&ss;
if (name != NULL) {
/* Resolve the host name. */
safe_strncpy(host, name, (sizeof host));
- if (ap->input(0, host, &sa) < 0) {
+ if (ap->input(0, host, sa) < 0) {
ap->herror(host);
return (-1);
}
- safe_strncpy(host, ap->sprint(&sa, 1), sizeof(host));
+ safe_strncpy(host, ap->sprint(sa, 1), sizeof(host));
}
/* Open the PROCps kernel table. */
if ((fp = fopen(_PATH_PROCNET_ARP, "r")) == NULL) {
strcpy(dev, "-");
/* Read the ARP cache entries. */
for (; fgets(line, sizeof(line), fp);) {
- num = sscanf(line, "%s 0x%x 0x%x %100s %100s %100s\n",
+ num = sscanf(line, "%s 0x%x 0x%x %99s %99s %99s\n",
ip, &type, &flags, hwa, mask, dev);
if (num < 4)
break;
if (opt_n)
hostname = "?";
else {
- if (ap->input(0, ip, &sa) < 0)
+ if (ap->input(0, ip, sa) < 0)
hostname = ip;
else
- hostname = ap->sprint(&sa, opt_n | 0x8000);
+ hostname = ap->sprint(sa, opt_n | 0x8000);
if (strcmp(hostname, ip) == 0)
hostname = "?";
}
static void usage(void)
{
fprintf(stderr, _("Usage:\n arp [-vn] [<HW>] [-i <if>] [-a] [<hostname>] <-Display ARP cache\n"));
- fprintf(stderr, _(" arp [-v] [-i <if>] -d <hostname> [pub][nopub] <-Delete ARP entry\n"));
- fprintf(stderr, _(" arp [-vnD] [<HW>] [-i <if>] -f [<filename>] <-Add entry from file\n"));
- fprintf(stderr, _(" arp [-v] [<HW>] [-i <if>] -s <hostname> <hwaddr> [temp][nopub] <-Add entry\n"));
- fprintf(stderr, _(" arp [-v] [<HW>] [-i <if>] -s <hostname> <hwaddr> [netmask <nm>] pub <-''-\n"));
- fprintf(stderr, _(" arp [-v] [<HW>] [-i <if>] -Ds <hostname> <if> [netmask <nm>] pub <-''-\n\n"));
+ fprintf(stderr, _(" arp [-v] [-i <if>] -d <host> [pub] <-Delete ARP entry\n"));
+ fprintf(stderr, _(" arp [-vnD] [<HW>] [-i <if>] -f [<filename>] <-Add entry from file\n"));
+ fprintf(stderr, _(" arp [-v] [<HW>] [-i <if>] -s <host> <hwaddr> [temp] <-Add entry\n"));
+ fprintf(stderr, _(" arp [-v] [<HW>] [-i <if>] -Ds <host> <if> [netmask <nm>] pub <-''-\n\n"));
fprintf(stderr, _(" -a display (all) hosts in alternative (BSD) style\n"));
+ fprintf(stderr, _(" -e display (all) hosts in default (Linux) style\n"));
fprintf(stderr, _(" -s, --set set a new ARP entry\n"));
fprintf(stderr, _(" -d, --delete delete a specified entry\n"));
fprintf(stderr, _(" -v, --verbose be verbose\n"));