Magellan Linux

Diff of /tags/mkinitrd-6_2_0/networking/arp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 13  Line 13 
13   * modified for getopt32 by Arne Bernin <arne [at] alamut.de>   * modified for getopt32 by Arne Bernin <arne [at] alamut.de>
14   */   */
15    
16  #include "busybox.h"  #include "libbb.h"
17  #include "inet_common.h"  #include "inet_common.h"
18    
19  #include <arpa/inet.h>  #include <arpa/inet.h>
# Line 27  Line 27 
27  #define DFLT_AF "inet"  #define DFLT_AF "inet"
28  #define DFLT_HW "ether"  #define DFLT_HW "ether"
29    
 #define _PATH_PROCNET_ARP "/proc/net/arp"  
   
30  #define ARP_OPT_A (0x1)  #define ARP_OPT_A (0x1)
31  #define ARP_OPT_p (0x2)  #define ARP_OPT_p (0x2)
32  #define ARP_OPT_H (0x4)  #define ARP_OPT_H (0x4)
# Line 46  static const struct aftype *ap; /* curre Line 44  static const struct aftype *ap; /* curre
44  static const struct hwtype *hw; /* current hardware type        */  static const struct hwtype *hw; /* current hardware type        */
45  static int sockfd;              /* active socket descriptor     */  static int sockfd;              /* active socket descriptor     */
46  static smallint hw_set;         /* flag if hw-type was set (-H) */  static smallint hw_set;         /* flag if hw-type was set (-H) */
47  static char *device = "";       /* current device               */  static const char *device = ""; /* current device               */
48    
49  static const char *const options[] = {  static const char options[] ALIGN1 =
50   "pub",   "pub\0"
51   "priv",   "priv\0"
52   "temp",   "temp\0"
53   "trail",   "trail\0"
54   "dontpub",   "dontpub\0"
55   "auto",   "auto\0"
56   "dev",   "dev\0"
57   "netmask",   "netmask\0";
  NULL  
 };  
58    
59  /* Delete an entry from the ARP cache. */  /* Delete an entry from the ARP cache. */
60  /* Called only from main, once */  /* Called only from main, once */
61  static int arp_del(char **args)  static int arp_del(char **args)
62  {  {
63   char host[128];   char *host;
64   struct arpreq req;   struct arpreq req;
65   struct sockaddr sa;   struct sockaddr sa;
66   int flags = 0;   int flags = 0;
# Line 73  static int arp_del(char **args) Line 69  static int arp_del(char **args)
69   memset(&req, 0, sizeof(req));   memset(&req, 0, sizeof(req));
70    
71   /* Resolve the host name. */   /* Resolve the host name. */
72   safe_strncpy(host, *args, 128);   host = *args;
73   if (ap->input(0, host, &sa) < 0) {   if (ap->input(host, &sa) < 0) {
74   bb_herror_msg_and_die("%s", host);   bb_herror_msg_and_die("%s", host);
75   }   }
76    
# Line 87  static int arp_del(char **args) Line 83  static int arp_del(char **args)
83   req.arp_flags = ATF_PERM;   req.arp_flags = ATF_PERM;
84   args++;   args++;
85   while (*args != NULL) {   while (*args != NULL) {
86   switch (index_in_str_array(options, *args)) {   switch (index_in_strings(options, *args)) {
87   case 0: /* "pub" */   case 0: /* "pub" */
88   flags |= 1;   flags |= 1;
89   args++;   args++;
# Line 130  static int arp_del(char **args) Line 126  static int arp_del(char **args)
126   if (*++args == NULL)   if (*++args == NULL)
127   bb_show_usage();   bb_show_usage();
128   if (strcmp(*args, "255.255.255.255") != 0) {   if (strcmp(*args, "255.255.255.255") != 0) {
129   safe_strncpy(host, *args, 128);   host = *args;
130   if (ap->input(0, host, &sa) < 0) {   if (ap->input(host, &sa) < 0) {
131   bb_herror_msg_and_die("%s", host);   bb_herror_msg_and_die("%s", host);
132   }   }
133   memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr));   memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr));
# Line 190  static void arp_getdevhw(char *ifname, s Line 186  static void arp_getdevhw(char *ifname, s
186   const struct hwtype *xhw;   const struct hwtype *xhw;
187    
188   strcpy(ifr.ifr_name, ifname);   strcpy(ifr.ifr_name, ifname);
189   if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {   ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr,
190   bb_perror_msg_and_die("cant get HW-Address for '%s'", ifname);   "cant get HW-Address for '%s'", ifname);
  }  
191   if (hwt && (ifr.ifr_hwaddr.sa_family != hw->type)) {   if (hwt && (ifr.ifr_hwaddr.sa_family != hw->type)) {
192   bb_error_msg_and_die("protocol type mismatch");   bb_error_msg_and_die("protocol type mismatch");
193   }   }
# Line 205  static void arp_getdevhw(char *ifname, s Line 200  static void arp_getdevhw(char *ifname, s
200   }   }
201   bb_error_msg("device '%s' has HW address %s '%s'",   bb_error_msg("device '%s' has HW address %s '%s'",
202   ifname, xhw->name,   ifname, xhw->name,
203   xhw->print((char *) &ifr.ifr_hwaddr.sa_data));   xhw->print((unsigned char *) &ifr.ifr_hwaddr.sa_data));
204   }   }
205  }  }
206    
# Line 213  static void arp_getdevhw(char *ifname, s Line 208  static void arp_getdevhw(char *ifname, s
208  /* Called only from main, once */  /* Called only from main, once */
209  static int arp_set(char **args)  static int arp_set(char **args)
210  {  {
211   char host[128];   char *host;
212   struct arpreq req;   struct arpreq req;
213   struct sockaddr sa;   struct sockaddr sa;
214   int flags;   int flags;
215    
216   memset(&req, 0, sizeof(req));   memset(&req, 0, sizeof(req));
217    
218   safe_strncpy(host, *args++, 128);   host = *args++;
219   if (ap->input(0, host, &sa) < 0) {   if (ap->input(host, &sa) < 0) {
220   bb_herror_msg_and_die("%s", host);   bb_herror_msg_and_die("%s", host);
221   }   }
222   /* If a host has more than one address, use the correct one! */   /* If a host has more than one address, use the correct one! */
# Line 242  static int arp_set(char **args) Line 237  static int arp_set(char **args)
237   /* Check out any modifiers. */   /* Check out any modifiers. */
238   flags = ATF_PERM | ATF_COM;   flags = ATF_PERM | ATF_COM;
239   while (*args != NULL) {   while (*args != NULL) {
240   switch (index_in_str_array(options, *args)) {   switch (index_in_strings(options, *args)) {
241   case 0: /* "pub" */   case 0: /* "pub" */
242   flags |= ATF_PUBL;   flags |= ATF_PUBL;
243   args++;   args++;
# Line 285  static int arp_set(char **args) Line 280  static int arp_set(char **args)
280   if (*++args == NULL)   if (*++args == NULL)
281   bb_show_usage();   bb_show_usage();
282   if (strcmp(*args, "255.255.255.255") != 0) {   if (strcmp(*args, "255.255.255.255") != 0) {
283   safe_strncpy(host, *args++, 128);   host = *args;
284   if (ap->input(0, host, &sa) < 0) {   if (ap->input(host, &sa) < 0) {
285   bb_herror_msg_and_die("%s", host);   bb_herror_msg_and_die("%s", host);
286   }   }
287   memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr));   memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr));
# Line 308  static int arp_set(char **args) Line 303  static int arp_set(char **args)
303   /* Call the kernel. */   /* Call the kernel. */
304   if (option_mask32 & ARP_OPT_v)   if (option_mask32 & ARP_OPT_v)
305   bb_error_msg("SIOCSARP()");   bb_error_msg("SIOCSARP()");
306   if (ioctl(sockfd, SIOCSARP, &req) < 0) {   xioctl(sockfd, SIOCSARP, &req);
  bb_perror_msg_and_die("SIOCSARP");  
  }  
307   return 0;   return 0;
308  }  }
309    
310    
311  /* Print the contents of an ARP request block. */  /* Print the contents of an ARP request block. */
312  static void  static void
313  arp_disp(char *name, char *ip, int type, int arp_flags,  arp_disp(const char *name, char *ip, int type, int arp_flags,
314   char *hwa, char *mask, char *dev)   char *hwa, char *mask, char *dev)
315  {  {
316     static const int arp_masks[] = {
317     ATF_PERM, ATF_PUBL,
318    #ifdef HAVE_ATF_MAGIC
319     ATF_MAGIC,
320    #endif
321    #ifdef HAVE_ATF_DONTPUB
322     ATF_DONTPUB,
323    #endif
324     ATF_USETRAILERS,
325     };
326     static const char arp_labels[] ALIGN1 = "PERM\0""PUP\0"
327    #ifdef HAVE_ATF_MAGIC
328     "AUTO\0"
329    #endif
330    #ifdef HAVE_ATF_DONTPUB
331     "DONTPUB\0"
332    #endif
333     "TRAIL\0"
334     ;
335    
336   const struct hwtype *xhw;   const struct hwtype *xhw;
337    
338   xhw = get_hwntype(type);   xhw = get_hwntype(type);
# Line 340  arp_disp(char *name, char *ip, int type, Line 353  arp_disp(char *name, char *ip, int type,
353   if (arp_flags & ATF_NETMASK)   if (arp_flags & ATF_NETMASK)
354   printf("netmask %s ", mask);   printf("netmask %s ", mask);
355    
356   if (arp_flags & ATF_PERM)   print_flags_separated(arp_masks, arp_labels, arp_flags, " ");
357   printf("PERM ");   printf(" on %s\n", dev);
  if (arp_flags & ATF_PUBL)  
  printf("PUP ");  
 #ifdef HAVE_ATF_MAGIC  
  if (arp_flags & ATF_MAGIC)  
  printf("AUTO ");  
 #endif  
 #ifdef HAVE_ATF_DONTPUB  
  if (arp_flags & ATF_DONTPUB)  
  printf("DONTPUB ");  
 #endif  
  if (arp_flags & ATF_USETRAILERS)  
  printf("TRAIL ");  
   
  printf("on %s\n", dev);  
358  }  }
359    
360  /* Display the contents of the ARP cache in the kernel. */  /* Display the contents of the ARP cache in the kernel. */
361  /* Called only from main, once */  /* Called only from main, once */
362  static int arp_show(char *name)  static int arp_show(char *name)
363  {  {
364   char host[100];   const char *host;
365     const char *hostname;
366     FILE *fp;
367   struct sockaddr sa;   struct sockaddr sa;
  char ip[100];  
  char hwa[100];  
  char mask[100];  
  char line[200];  
  char dev[100];  
368   int type, flags;   int type, flags;
  FILE *fp;  
  char *hostname;  
369   int num;   int num;
370   unsigned entries = 0, shown = 0;   unsigned entries = 0, shown = 0;
371     char ip[128];
372     char hwa[128];
373     char mask[128];
374     char line[128];
375     char dev[128];
376    
377   host[0] = '\0';   host = NULL;
   
378   if (name != NULL) {   if (name != NULL) {
379   /* Resolve the host name. */   /* Resolve the host name. */
380   safe_strncpy(host, name, (sizeof host));   if (ap->input(name, &sa) < 0) {
381   if (ap->input(0, host, &sa) < 0) {   bb_herror_msg_and_die("%s", name);
  bb_herror_msg_and_die("%s", host);  
382   }   }
383   safe_strncpy(host, ap->sprint(&sa, 1), sizeof(host));   host = xstrdup(ap->sprint(&sa, 1));
384   }   }
385   /* Open the PROCps kernel table. */   fp = xfopen_for_read("/proc/net/arp");
386   fp = xfopen(_PATH_PROCNET_ARP, "r");   /* Bypass header -- read one line */
387   /* Bypass header -- read until newline */   fgets(line, sizeof(line), fp);
388   if (fgets(line, sizeof(line), fp) != (char *) NULL) {  
389     /* Read the ARP cache entries. */
390     while (fgets(line, sizeof(line), fp)) {
391    
392   mask[0] = '-'; mask[1] = '\0';   mask[0] = '-'; mask[1] = '\0';
393   dev[0] = '-'; dev[1] = '\0';   dev[0] = '-'; dev[1] = '\0';
394   /* Read the ARP cache entries. */   /* All these strings can't overflow
395   for (; fgets(line, sizeof(line), fp);) {   * because fgets above reads limited amount of data */
396   num = sscanf(line, "%s 0x%x 0x%x %100s %100s %100s\n",   num = sscanf(line, "%s 0x%x 0x%x %s %s %s\n",
397   ip, &type, &flags, hwa, mask, dev);   ip, &type, &flags, hwa, mask, dev);
398   if (num < 4)   if (num < 4)
399   break;   break;
400    
401   entries++;   entries++;
402   /* if the user specified hw-type differs, skip it */   /* if the user specified hw-type differs, skip it */
403   if (hw_set && (type != hw->type))   if (hw_set && (type != hw->type))
404   continue;   continue;
405    
406   /* if the user specified address differs, skip it */   /* if the user specified address differs, skip it */
407   if (host[0] && strcmp(ip, host) != 0)   if (host && strcmp(ip, host) != 0)
408   continue;   continue;
409    
410   /* if the user specified device differs, skip it */   /* if the user specified device differs, skip it */
411   if (device[0] && strcmp(dev, device) != 0)   if (device[0] && strcmp(dev, device) != 0)
412   continue;   continue;
413    
414   shown++;   shown++;
415   /* This IS ugly but it works -be */   /* This IS ugly but it works -be */
416   if (option_mask32 & ARP_OPT_n)   hostname = "?";
417     if (!(option_mask32 & ARP_OPT_n)) {
418     if (ap->input(ip, &sa) < 0)
419     hostname = ip;
420     else
421     hostname = ap->sprint(&sa, (option_mask32 & ARP_OPT_n) | 0x8000);
422     if (strcmp(hostname, ip) == 0)
423   hostname = "?";   hostname = "?";
  else {  
  if (ap->input(0, ip, &sa) < 0)  
  hostname = ip;  
  else  
  hostname = ap->sprint(&sa, (option_mask32 & ARP_OPT_n) | 0x8000);  
  if (strcmp(hostname, ip) == 0)  
  hostname = "?";  
  }  
   
  arp_disp(hostname, ip, type, flags, hwa, mask, dev);  
424   }   }
425    
426     arp_disp(hostname, ip, type, flags, hwa, mask, dev);
427   }   }
428   if (option_mask32 & ARP_OPT_v)   if (option_mask32 & ARP_OPT_v)
429   printf("Entries: %d\tSkipped: %d\tFound: %d\n",   printf("Entries: %d\tSkipped: %d\tFound: %d\n",
430     entries, entries - shown, shown);     entries, entries - shown, shown);
431    
432   if (!shown) {   if (!shown) {
433   if (hw_set || host[0] || device[0])   if (hw_set || host || device[0])
434   printf("No match found in %d entries\n", entries);   printf("No match found in %d entries\n", entries);
435   }   }
436     if (ENABLE_FEATURE_CLEAN_UP) {
437   fclose(fp);   free((char*)host);
438     fclose(fp);
439     }
440   return 0;   return 0;
441  }  }
442    
443  int arp_main(int argc, char **argv)  int arp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
444    int arp_main(int argc UNUSED_PARAM, char **argv)
445  {  {
446   char *hw_type;   const char *hw_type = "ether";
447   char *protocol;   const char *protocol;
448    
449   /* Initialize variables... */   /* Initialize variables... */
450   ap = get_aftype(DFLT_AF);   ap = get_aftype(DFLT_AF);
451   if (!ap)   if (!ap)
452   bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family");   bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family");
453    
454   getopt32(argc, argv, "A:p:H:t:i:adnDsv", &protocol, &protocol,   getopt32(argv, "A:p:H:t:i:adnDsv", &protocol, &protocol,
455   &hw_type, &hw_type, &device);   &hw_type, &hw_type, &device);
456   argv += optind;   argv += optind;
457   if (option_mask32 & ARP_OPT_A || option_mask32 & ARP_OPT_p) {   if (option_mask32 & ARP_OPT_A || option_mask32 & ARP_OPT_p) {

Legend:
Removed from v.532  
changed lines
  Added in v.816