Справочник по консольным командам Toybox для Android 12


  Ver.0.8.4     Ver.0.8.9     Pending  

Путь: Toys/Pending, команды версии: Ver.4     Ver.9


arp

Комментарии в файле arp.c :

usage: arp

[-vn] [-H HWTYPE] [-i IF] -a [ИМЯ ХОСТА] [-v] [-i ЕСЛИ] -d ИМЯ ХОСТА [pub] [-v] [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp] [-v] [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [маска сети MASK] pub [-v] [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [маска сети MASK] pub Управление кешем ARP.
  • -a Показать (все) хосты
  • -s Установить новую запись ARP
  • -d Удалить указанную запись
  • -v Подробно
  • -n Не разрешать имена
  • -i IFACE Сетевой интерфейс
  • -D Чтение <hwaddr> с данного устройства
  • -A,-p Семейство протоколов AF
  • -H HWTYPE Тип аппаратного адреса

  • usage: arp

    [-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME] [-v] [-i IF] -d HOSTNAME [pub] [-v] [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp] [-v] [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub [-v] [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub Manipulate ARP cache.
  • -a Display (all) hosts
  • -s Set new ARP entry
  • -d Delete a specified entry
  • -v Verbose
  • -n Don't resolve names
  • -i IFACE Network interface
  • -D Read <hwaddr> from given device
  • -A,-p AF Protocol family
  • -H HWTYPE Hardware address type

  • Исходный текст в файле arp.c

    #define FOR_arp
    #include "toys.h"
    #include <net/if_arp.h>
    
    GLOBALS(
        char *hw_type;
        char *af_type_A;
        char *af_type_p;
        char *interface;
    
        int sockfd;
        char *device;
    )
    
    struct arpreq req;
    
    struct type {
      char *name;
      int val;
    };
    
    struct type hwtype[] = {
      {"ether", ARPHRD_ETHER },
      {"loop" ,ARPHRD_LOOPBACK},
      {"ppp" ,ARPHRD_PPP},
      {"infiniband" ,ARPHRD_INFINIBAND},
      {NULL, -1},
    };
    
    struct type aftype[] = {
      {"inet", AF_INET },
      {"inet6" ,AF_INET6},
      {"unspec" ,AF_UNSPEC},
      {NULL, -1},
    };
    
    struct type flag_type[] = {
      {"PERM", ATF_PERM },
      {"PUB" ,ATF_PUBL},
      {"DONTPUB" ,ATF_DONTPUB},
      {"TRAIL" ,ATF_USETRAILERS},
      {NULL, -1},
    };
    
    static int get_index(struct type arr[], char *name)
    {
      int i;
    
      for (i = 0; arr[i].name; i++)
        if (!strcmp(arr[i].name, name)) break;
      return arr[i].val;
    }
    
    static void resolve_host(char *host, struct sockaddr *sa)
    {
      struct addrinfo *ai = xgetaddrinfo(host, NULL, AF_INET, SOCK_STREAM, 0, 0);
    
      memcpy(sa, ai->ai_addr, ai->ai_addrlen);
      freeaddrinfo(ai);
    }
    
    static void check_flags(int *i, char** argv)
    {
      struct sockaddr sa;
      int flag = *i, j;
      struct flags {
        char *name;
        int or, flag;
      } f[] = {
        {"pub",  1 ,ATF_PUBL},
        {"priv", 0 ,~ATF_PUBL},
        {"trail", 1, ATF_USETRAILERS},
        {"temp", 0, ~ATF_PERM},
        {"dontpub",1, ATF_DONTPUB},
      };
      
      for (;*argv; argv++) {
        for (j = 0;  j < ARRAY_LEN(f); j++) { 
          if (!strcmp(*argv, f[j].name)) {
            (f[j].or) ?(flag |= f[j].flag):(flag &= f[j].flag);
            break;
          }
        }
        if (j > 4 && !strcmp(*argv, "netmask")) {
          if (!*++argv) error_exit("NULL netmask");
          if (strcmp(*argv, "255.255.255.255")) {
            resolve_host(toys.optargs[0], &sa);
            memcpy(&req.arp_netmask, &sa, sizeof(sa));
            flag |= ATF_NETMASK;
          } else argv++; 
        } else if (j > 4 && !strcmp(*argv, "dev")) {
          if (!*++argv) error_exit("NULL dev");
          TT.device = *argv;
        } else if (j > 4) error_exit("invalid arg");
      }
      *i = flag;
    }
    
    static int set_entry(void) 
    {
      int flags = 0;
      
      if (!toys.optargs[1]) error_exit("bad syntax");
    
      if (!FLAG(D)) {
        char *ptr = toys.optargs[1];
        char *p = ptr, *hw_addr = req.arp_ha.sa_data;
    
        while (*hw_addr && (p-ptr) < 6) {
          int val, len;
    
          if (*hw_addr == ':') hw_addr++;
          if (!sscanf(hw_addr, "%2x%n", &val, &len)) break;
          hw_addr += len;
          *p++ = val;
        }
    
        if ((p-ptr) != 6 || *hw_addr)
          error_exit("bad hw addr '%s'", req.arp_ha.sa_data);
      } else {
        struct ifreq ifre;
    
        xstrncpy(ifre.ifr_name, toys.optargs[1], IFNAMSIZ);
        xioctl(TT.sockfd, SIOCGIFHWADDR, &ifre);
        if (FLAG(H) && ifre.ifr_hwaddr.sa_family != ARPHRD_ETHER)
          error_exit("protocol type mismatch");
        memcpy(&req.arp_ha, &(ifre.ifr_hwaddr), sizeof(req.arp_ha));
      }
    
      flags = ATF_PERM | ATF_COM;
      if (toys.optargs[2]) check_flags(&flags, (toys.optargs+2));
      req.arp_flags = flags;
      xstrncpy(req.arp_dev, TT.device, sizeof(req.arp_dev));
      xioctl(TT.sockfd, SIOCSARP, &req);
    
      if (FLAG(v)) xprintf("Entry set for %s\n", toys.optargs[0]);
      return 0;
    }
    
    static int ip_to_host(struct sockaddr *sa, int flag)
    {
      int status = 0;
      char hbuf[NI_MAXHOST] = {0,}, sbuf[NI_MAXSERV] = {0,}; 
      socklen_t len = sizeof(struct sockaddr_in6);
      
      *toybuf = 0;
      if (!(status = getnameinfo(sa, len, hbuf, sizeof(hbuf), sbuf, 
              sizeof(sbuf), flag))) {
        strcpy(toybuf, hbuf);
        return 0;
      }
      return 1;
    }
    
    static int delete_entry(void)
    {
      int flags = ATF_PERM;
    
      if (toys.optargs[1]) check_flags(&flags, (toys.optargs+1));
      req.arp_flags = flags;
      xstrncpy(req.arp_dev, TT.device, sizeof(req.arp_dev));
      xioctl(TT.sockfd, SIOCDARP, &req);
    
      if (FLAG(v)) xprintf("Delete entry for  %s\n", toys.optargs[0]);
      return 0;
    }
    
    void arp_main(void)
    {
      struct sockaddr sa;
      char ip[16], hw_addr[30], mask[16], dev[16], *host_ip = NULL;
      FILE *fp;
      int h_type, type, flag, i, entries = 0, disp = 0;
    
      TT.device = "";
      memset(&sa, 0, sizeof(sa));
      TT.sockfd = xsocket(AF_INET, SOCK_STREAM, 0);
    
      if (FLAG(A) || FLAG(p)) {
        if ((type = get_index(aftype,
                (TT.af_type_A)?TT.af_type_A:TT.af_type_p)) != AF_INET)
          error_exit((type != -1)?"only inet supported by kernel":"unknown family");
      }
    
      req.arp_ha.sa_family = ARPHRD_ETHER;
      if (FLAG(H)) {
        if ((type = get_index(hwtype, TT.hw_type)) != ARPHRD_ETHER)
          error_exit((type != -1)?"h/w type not supported":"unknown h/w type");
        req.arp_ha.sa_family = type;
      }
    
      if (FLAG(s) || FLAG(d)) {
        if (!toys.optargs[0]) error_exit("-%c needs a host name", FLAG(d)?'d':'s');
        resolve_host(toys.optargs[0], &sa);
        memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr));
    
        if (FLAG(s) && !set_entry()) return;
        if (FLAG(d) && !delete_entry()) return;
      }
    
      // Show arp cache.
    
      if (toys.optargs[0]) {
        resolve_host(toys.optargs[0], &sa);
        ip_to_host(&sa, NI_NUMERICHOST);
        host_ip = xstrdup(toybuf);
      }
    
      fp = xfopen("/proc/net/arp", "r");
      fgets(toybuf, sizeof(toybuf), fp); // Skip header.
      while (fscanf(fp, "%15s 0x%x 0x%x %29s %15s %15s",
                    ip, &h_type, &flag, hw_addr, mask, dev) == 6) {
        char *host_name = "?";
    
        entries++;
        if ((FLAG(H) && get_index(hwtype, TT.hw_type) != h_type) ||
          (FLAG(i) && strcmp(TT.interface, dev)) ||
          (toys.optargs[0] && strcmp(host_ip, ip))) {
          continue;
        }
    
        resolve_host(ip, &sa);
        if (FLAG(n)) ip_to_host(&sa, NI_NUMERICHOST);
        else if (!ip_to_host(&sa, NI_NAMEREQD)) host_name = toybuf;
    
        disp++;
        printf("%s (%s) at" , host_name, ip);
    
        for (i = 0; hwtype[i].name; i++)
          if (hwtype[i].val & h_type) break;
        if (!hwtype[i].name) error_exit("unknown h/w type");
    
        if (!(flag & ATF_COM)) {
          if ((flag & ATF_PUBL)) printf(" *");
          else printf(" <incomplete>");
        } else printf(" %s [%s]", hw_addr, hwtype[i].name);
    
        if (flag & ATF_NETMASK) printf("netmask %s ", mask);
    
        for (i = 0; flag_type[i].name; i++)
          if (flag_type[i].val & flag) printf(" %s", flag_type[i].name);
    
        printf(" on %s\n", dev);
      }
    
      if (FLAG(v))
        xprintf("Entries: %d\tSkipped: %d\tFound: %d\n",
            entries, entries - disp, disp);
      if (toys.optargs[0] && !disp)
        xprintf("%s (%s) -- no entry\n", toys.optargs[0], host_ip);
    
      if (CFG_TOYBOX_FREE) {
        free(host_ip);
        fclose(fp);
      }
    }