aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toys/pending/ifconfig.c165
1 files changed, 67 insertions, 98 deletions
diff --git a/toys/pending/ifconfig.c b/toys/pending/ifconfig.c
index df462f33..111e4bbd 100644
--- a/toys/pending/ifconfig.c
+++ b/toys/pending/ifconfig.c
@@ -47,20 +47,6 @@ typedef struct sockaddr_with_len {
} sock_u;
} sockaddr_with_len;
-// man netdevice
-struct if_list {
- struct if_list *next;
- int hw_type, mtu, metric, txqueuelen, non_virtual_iface;
- short flags;
- struct sockaddr addr, dstaddr, broadaddr, netmask, hwaddr;
- struct ifmap map;
-
- char name[IFNAMSIZ];
- unsigned long long val[16];
-};
-
-#define IO_MAP_INDEX 0x100
-
//for the param settings.
//for ipv6 add/del
@@ -157,41 +143,9 @@ static void set_address(char *host_name, struct ifreq *ifre, int request)
xioctl(TT.sockfd, request, ifre);
}
-static void get_device_info(char *name, struct if_list *il)
+static void display_ifconfig(char *name, int always, unsigned long long val[])
{
struct ifreq ifre;
-
- il->txqueuelen = -1;
-
- xstrncpy(ifre.ifr_name, name, IFNAMSIZ);
- if (ioctl(TT.sockfd, SIOCGIFFLAGS, &ifre)<0) perror_exit("%s", il->name);
- il->flags = ifre.ifr_flags;
-
- if (ioctl(TT.sockfd, SIOCGIFHWADDR, &ifre) >= 0)
- memcpy(il->hwaddr.sa_data, ifre.ifr_hwaddr.sa_data, sizeof(il->hwaddr.sa_data));
- il->hw_type = ifre.ifr_hwaddr.sa_family;
-
- if (ioctl(TT.sockfd, SIOCGIFMETRIC, &ifre) >= 0)
- il->metric = ifre.ifr_metric;
- if (ioctl(TT.sockfd, SIOCGIFMTU, &ifre) >= 0) il->mtu = ifre.ifr_mtu;
- if (ioctl(TT.sockfd, SIOCGIFMAP, &ifre) == 0) il->map = ifre.ifr_map;
- if (ioctl(TT.sockfd, SIOCGIFTXQLEN, &ifre) >= 0)
- il->txqueuelen = ifre.ifr_qlen;
-
- // If an address is assigned record that.
-
- ifre.ifr_addr.sa_family = AF_INET;
- if (!ioctl(TT.sockfd, SIOCGIFADDR, &ifre)) il->addr = ifre.ifr_addr;
- if (ioctl(TT.sockfd, SIOCGIFDSTADDR, &ifre) >= 0)
- il->dstaddr = ifre.ifr_dstaddr;
- if (ioctl(TT.sockfd, SIOCGIFBRDADDR, &ifre) >= 0)
- il->broadaddr = ifre.ifr_broadaddr;
- if (ioctl(TT.sockfd, SIOCGIFNETMASK, &ifre) >= 0)
- il->netmask = ifre.ifr_netmask;
-}
-
-static void display_ifconfig(char *name, struct if_list *il)
-{
struct {
int type;
char *title;
@@ -203,41 +157,57 @@ static void display_ifconfig(char *name, struct if_list *il)
int i;
char *p;
FILE *fp;
+ short flags;
+
+ xstrncpy(ifre.ifr_name, name, IFNAMSIZ);
+ if (ioctl(TT.sockfd, SIOCGIFFLAGS, &ifre)<0) perror_exit("%s", name);
+ flags = ifre.ifr_flags;
+ if (!always && !(flags & IFF_UP)) return;
+
+ // query hardware type and hardware address
+ i = ioctl(TT.sockfd, SIOCGIFHWADDR, &ifre);
for (i=0; i < (sizeof(types)/sizeof(*types))-1; i++)
- if (il->hw_type == types[i].type) break;
+ if (ifre.ifr_hwaddr.sa_family == types[i].type) break;
xprintf("%-9s Link encap:%s ", name, types[i].title);
- if(il->hwaddr.sa_data && il->hw_type == ARPHRD_ETHER) {
+ if(i >= 0 && ifre.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
xprintf("HWaddr ");
- for (i=0; i<6; i++) xprintf(":%02X"+!i, il->hwaddr.sa_data[i]);
+ for (i=0; i<6; i++) xprintf(":%02X"+!i, ifre.ifr_hwaddr.sa_data[i]);
}
xputc('\n');
- p = (char *)&il->addr;
- for (i = 0; i<sizeof(il->addr); i++) if (p[i]) break;
- if (i != sizeof(il->addr)) {
- int af = il->addr.sa_family;
+ // If an address is assigned record that.
+
+ ifre.ifr_addr.sa_family = AF_INET;
+ memset(&ifre.ifr_addr, 0, sizeof(ifre.ifr_addr));
+ ioctl(TT.sockfd, SIOCGIFADDR, &ifre);
+ p = (char *)&ifre.ifr_addr;
+ for (i = 0; i<sizeof(ifre.ifr_addr); i++) if (p[i]) break;
+
+ if (i != sizeof(ifre.ifr_addr)) {
+ struct sockaddr_in *si = (struct sockaddr_in *)&ifre.ifr_addr;
struct {
char *name;
- int flag, offset;
+ int flag, ioctl;
} 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)}
+ {"addr", 0, 0},
+ {"P-t-P", IFF_POINTOPOINT, SIOCGIFDSTADDR},
+ {"Bcast", IFF_BROADCAST, SIOCGIFBRDADDR},
+ {"Mask", 0, SIOCGIFNETMASK}
};
- xprintf("%10c%s", ' ',
- (af == AF_INET) ? "inet" : (af == AF_INET6) ? "inet6" : "unspec");
+ xprintf("%10c%s", ' ', (si->sin_family == AF_INET) ? "inet" :
+ (si->sin_family == AF_INET6) ? "inet6" : "unspec");
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))
+ if (!addr[i].flag || (flags & addr[i].flag)) {
+ if (addr[i].ioctl && ioctl(TT.sockfd, addr[i].ioctl, &ifre))
+ si->sin_family = 0;
xprintf(" %s:%s ", addr[i].name,
- (s->sin_family == 0xFFFF || !s->sin_family) ? "[NOT SET]" :
- inet_ntoa(s->sin_addr));
+ (si->sin_family == 0xFFFF || !si->sin_family)
+ ? "[NOT SET]" : inet_ntoa(si->sin_addr));
+ }
}
xputc('\n');
@@ -288,7 +258,7 @@ static void display_ifconfig(char *name, struct if_list *il)
xprintf("%10c", ' ');
- if (il->flags) {
+ if (flags) {
unsigned short mask = 1;
char **s, *str[] = {
"UP", "BROADCAST", "DEBUG", "LOOPBACK", "POINTOPOINT", "NOTRAILERS",
@@ -297,15 +267,20 @@ static void display_ifconfig(char *name, struct if_list *il)
};
for(s = str; *s; s++) {
- if(il->flags & mask) xprintf("%s ", *s);
+ if(flags & mask) xprintf("%s ", *s);
mask = mask << 1;
}
} else xprintf("[NO FLAGS] ");
- if(!il->metric) il->metric = 1;
- xprintf(" MTU:%d Metric:%d", il->mtu, il->metric);
+ if (ioctl(TT.sockfd, SIOCGIFMTU, &ifre) < 0) ifre.ifr_mtu = 0;
+ xprintf(" MTU:%d", ifre.ifr_mtu);
+ if (ioctl(TT.sockfd, SIOCGIFMETRIC, &ifre) < 0) ifre.ifr_metric = 0;
+ if (!ifre.ifr_metric) ifre.ifr_metric = 1;
+ xprintf(" Metric:%d", ifre.ifr_metric);
- if(il->non_virtual_iface) {
+ // non-virtual interface
+
+ if(val) {
char *label[] = {"RX bytes", "RX packets", "errors", "dropped", "overruns",
"frame", 0, 0, "TX bytes", "TX packets", "errors", "dropped", "overruns",
"collisions", "carrier", 0, "txqueuelen"};
@@ -313,24 +288,29 @@ static void display_ifconfig(char *name, struct if_list *il)
13, 16, -1, 0, 8};
int i;
+ // Query txqueuelen
+ if (ioctl(TT.sockfd, SIOCGIFTXQLEN, &ifre) >= 0) val[16] = ifre.ifr_qlen;
+ else val[16] = -1;
+
for (i = 0; i < sizeof(order); i++) {
int j = order[i];
if (j < 0) xprintf("\n%10c", ' ');
- else xprintf("%s:%llu ", label[j],
- j==16 ? (unsigned long long)il->txqueuelen : il->val[j]);
+ else xprintf("%s:%llu ", label[j], val[j]);
}
}
xputc('\n');
- if(il->map.irq || il->map.mem_start || il->map.dma || il->map.base_addr) {
+ if(!ioctl(TT.sockfd, SIOCGIFMAP, &ifre) && (ifre.ifr_map.irq ||
+ ifre.ifr_map.mem_start || ifre.ifr_map.dma || ifre.ifr_map.base_addr))
+ {
xprintf("%10c", ' ');
- if(il->map.irq) xprintf("Interrupt:%d ", il->map.irq);
- if(il->map.base_addr >= IO_MAP_INDEX)
- xprintf("Base address:0x%lx ", il->map.base_addr);
- if(il->map.mem_start)
- xprintf("Memory:%lx-%lx ", il->map.mem_start, il->map.mem_end);
- if(il->map.dma) xprintf("DMA chan:%x ", il->map.dma);
+ if(ifre.ifr_map.irq) xprintf("Interrupt:%d ", ifre.ifr_map.irq);
+ if(ifre.ifr_map.base_addr >= 0x100) // IO_MAP_INDEX
+ xprintf("Base address:0x%lx ", ifre.ifr_map.base_addr);
+ if(ifre.ifr_map.mem_start)
+ xprintf("Memory:%lx-%lx ", ifre.ifr_map.mem_start, ifre.ifr_map.mem_end);
+ if(ifre.ifr_map.dma) xprintf("DMA chan:%x ", ifre.ifr_map.dma);
xputc('\n');
}
xputc('\n');
@@ -339,7 +319,6 @@ static void display_ifconfig(char *name, struct if_list *il)
static void show_iface(char *iface_name)
{
char *name;
- struct if_list il;
struct string_list *ifaces = 0, *sl;
int i, j;
FILE *fp;
@@ -348,6 +327,7 @@ static void show_iface(char *iface_name)
for (i=0; fgets(toybuf, sizeof(toybuf), fp); i++) {
char *buf = toybuf;
+ unsigned long long val[17];
if (i<2) continue;
@@ -356,15 +336,12 @@ static void show_iface(char *iface_name)
if(!buf) error_exit("bad name %s", name);
errno = 0;
- for (j=0; j<16 && !errno; j++) il.val[j] = strtoll(buf, &buf, 0);
+ for (j=0; j<16 && !errno; j++) val[j] = strtoll(buf, &buf, 0);
if (errno) perror_exit("bad %s at %s", name, buf);
- il.non_virtual_iface = 1;
-
if (iface_name) {
if (!strcmp(iface_name, name)) {
- get_device_info(name, &il);
- display_ifconfig(name, &il);
+ display_ifconfig(name, 1, val);
return;
}
@@ -374,17 +351,13 @@ static void show_iface(char *iface_name)
sl->next = ifaces;
ifaces = sl;
- get_device_info(name, &il);
- if ((il.flags & IFF_UP) || (toys.optflags & FLAG_a))
- display_ifconfig(name, &il);
+ display_ifconfig(name, toys.optflags & FLAG_a, val);
}
}
fclose(fp);
- if (iface_name) {
- get_device_info(iface_name, &il);
- display_ifconfig(iface_name, &il);
- } else {
+ if (iface_name) display_ifconfig(iface_name, 1, 0);
+ else {
struct ifconf ifcon;
struct ifreq *ifre;
int num;
@@ -405,11 +378,7 @@ static void show_iface(char *iface_name)
for(sl = ifaces; sl; sl = sl->next)
if(!strcmp(sl->str, ifre->ifr_name)) break;
- if(!sl) {
- get_device_info(ifre->ifr_name, &il);
- if ((il.flags & IFF_UP) || (toys.optflags & FLAG_a))
- display_ifconfig(ifre->ifr_name, &il);
- }
+ if(!sl) display_ifconfig(ifre->ifr_name, toys.optflags & FLAG_a, 0);
}
free(ifcon.ifc_buf);