# define SIOCGOUTFILL (SIOCDEVPRIVATE+3) /* Get outfill timeout */
#endif
-#ifndef INFINIBAND_ALEN
-# define INFINIBAND_ALEN 20
-#endif
-
/*
* used to extract the address info from the given host ip
* and update the swl param accordingly.
}
}
-static int hex_to_binary(char *hw_addr, struct sockaddr *sock, int count)
-{
- int i = 0, j = 0;
- unsigned char nib_val, ch;
-
- char *ptr = (char *) sock->sa_data;
- if (count == ETH_ALEN) sock->sa_family = ARPHRD_ETHER;
- else if (count == INFINIBAND_ALEN) sock->sa_family = ARPHRD_INFINIBAND;
- else return -1;
- //e.g. hw_addr "62:2D:A6:9E:2D:BE"
- for (; *hw_addr && (i < count); i++) {
- if (*hw_addr == ':') hw_addr++;
- j = nib_val = 0;
- for (;j < 2; j++) {
- ch = *hw_addr;
- //0-9 = 10 chars.
- if (((unsigned char)(ch - '0')) < 10) ch = (ch - '0');
- //a-f = 6 chars.
- else if (((unsigned char)((ch) - 'a')) < 6) ch = (ch - ('a'-10));
- //A-F = 6 chars.
- else if (((unsigned char)((ch) - 'A')) < 6) ch = (ch - ('A'-10));
- else if (j && (ch == ':' || ch == 0)) break;
- else return -1;
- hw_addr++;
- nib_val <<= 4;
- nib_val += ch;
- }
- *ptr++ = nib_val;
- }
- if (*hw_addr) return -1;
- return 0;
-}
-
-static void set_hw_address(int sockfd, char ***argv, struct ifreq *ifre, int request)
-{
- int hw_class = 0;
- char *hw_addr;
- struct sockaddr sock;
- char *ptr;
- char *hw_class_strings[] = {
- "ether",
- "infiniband",
- NULL
- };
-
- if(strcmp(hw_class_strings[0], **argv) == 0)
- hw_class = 1;
- else if(strcmp(hw_class_strings[1], **argv) == 0)
- hw_class = 2;
- if(!hw_class || !(*argv += 1)) {
- errno = EINVAL;
- toys.exithelp++;
- error_exit("bad hardware class");
- }
-
- memset(&sock, 0, sizeof(struct sockaddr));
- hw_addr = **argv;
- if(hex_to_binary(hw_addr, &sock, hw_class == 1 ? ETH_ALEN : INFINIBAND_ALEN))
- error_exit("bad hw-addr %s", hw_addr);
- ptr = (char *)&sock;
- memcpy( ((char *) ifre) + offsetof(struct ifreq, ifr_hwaddr), ptr, sizeof(struct sockaddr));
- xioctl(sockfd, request, ifre);
-}
-
static void add_iface_to_list(struct if_list *newnode)
{
struct if_list *head_ref = TT.if_list;
close(sokfd);
}
-static void show_ip_addr(char *name, struct sockaddr *skaddr)
-{
- char *s = "[NOT SET]";
-
- if(skaddr->sa_family != 0xFFFF && skaddr->sa_family)
- s = inet_ntoa(((struct sockaddr_in *)skaddr)->sin_addr);
-
- xprintf(" %s:%s ", name, s);
-}
-
static void print_ip6_addr(struct if_list *il)
{
char iface_name[IFNAMSIZ] = {0,};
if(il->hasaddr) {
int af = il->addr.sa_family;
- char *name = "unspec";
+ struct {
+ char *name;
+ int flag, offset;
+ } addr[] = {
+ {"addr", 0, offsetof(struct if_list, addr)},
+ {"P-t-P", IFF_POINTOPOINT, offsetof(struct if_list, dstaddr)},
+ {"Bcast", IFF_BROADCAST, offsetof(struct if_list, broadaddr)},
+ {"Mask", 0, offsetof(struct if_list, netmask)}
+ };
+
+ xprintf("%10c%s", ' ',
+ (af == AF_INET) ? "inet" : (af == AF_INET6) ? "inet6" : "unspec");
- if (af == AF_INET) name = "inet";
- else if (af == AF_INET6) name = "inet6";
- xprintf("%10c%s", ' ', name);
+ for (i=0; i < sizeof(addr)/sizeof(*addr); i++) {
+ struct sockaddr_in *s = (struct sockaddr_in *)(addr[i].offset+(char *)il);
+
+ if (!addr[i].flag || (il->flags & addr[i].flag))
+ xprintf(" %s:%s ", addr[i].name,
+ (s->sin_family == 0xFFFF || !s->sin_family) ? "[NOT SET]" :
+ inet_ntoa(s->sin_addr));
+ }
- show_ip_addr("addr", &il->addr);
- if(il->flags & IFF_POINTOPOINT) show_ip_addr("P-t-P", &il->dstaddr);
- if(il->flags & IFF_BROADCAST) show_ip_addr("Bcast", &il->broadaddr);
- show_ip_addr("Mask", &il->netmask);
xputc('\n');
}
if (i != sizeof(try)/sizeof(*try)) continue;
if (!strcmp(*argv, "hw")) {
+ char *hw_addr, *ptr, *p;
+ struct sockaddr *sock = &ifre.ifr_hwaddr;
+ int count = 6;
+
if (!*++argv) show_help();
- set_hw_address(sockfd, &argv, &ifre, SIOCSIFHWADDR);
+ memset(sock, 0, sizeof(struct sockaddr));
+ if (!strcmp("ether", *argv)) sock->sa_family = ARPHRD_ETHER;
+ else if (!strcmp("infiniband", *argv)) {
+ sock->sa_family = ARPHRD_INFINIBAND;
+ count = 20;
+ } else {
+ toys.exithelp++;
+ error_exit("bad hw '%s'", *argv);
+ }
+ hw_addr = *++argv;
+
+ ptr = p = (char *) sock->sa_data;
+
+ while (*hw_addr && (p-ptr) < count) {
+ int val, len = 0;
+
+ if (*hw_addr == ':') hw_addr++;
+ sscanf(hw_addr, "%2x%n", &val, &len);
+ if (len != 2) break;
+ hw_addr += len;
+ *p++ = val;
+ }
+
+ if ((p-ptr) != count || *hw_addr)
+ error_exit("bad hw-addr '%s'", hw_addr ? hw_addr : "");
+ xioctl(sockfd, SIOCSIFHWADDR, &ifre);
} else if (!strcmp(*argv, "mtu")) {
if (!*++argv) show_help();
ifre.ifr_mtu = strtoul(*argv, NULL, 0);