aboutsummaryrefslogtreecommitdiff
path: root/toys/pending/ifconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/pending/ifconfig.c')
-rw-r--r--toys/pending/ifconfig.c197
1 files changed, 67 insertions, 130 deletions
diff --git a/toys/pending/ifconfig.c b/toys/pending/ifconfig.c
index 2864e3f9..df462f33 100644
--- a/toys/pending/ifconfig.c
+++ b/toys/pending/ifconfig.c
@@ -36,8 +36,6 @@ config IFCONFIG
#include <net/ethernet.h>
GLOBALS(
- void *if_list;
-
int sockfd;
)
@@ -46,8 +44,7 @@ typedef struct sockaddr_with_len {
struct sockaddr sock;
struct sockaddr_in sock_in;
struct sockaddr_in6 sock_in6;
- }sock_u;
- socklen_t socklen;
+ } sock_u;
} sockaddr_with_len;
// man netdevice
@@ -88,7 +85,6 @@ sockaddr_with_len *get_sockaddr(char *host, int port, sa_family_t af)
struct sockaddr_un *sockun;
swl = xzalloc(sizeof(struct sockaddr_with_len));
- swl->socklen = sizeof(struct sockaddr_un);
swl->sock_u.sock.sa_family = AF_UNIX;
sockun = (struct sockaddr_un *)&swl->sock_u.sock;
xstrncpy(sockun->sun_path, host + 6, sizeof(sockun->sun_path));
@@ -128,7 +124,6 @@ sockaddr_with_len *get_sockaddr(char *host, int port, sa_family_t af)
for (rp = result; rp; rp = rp->ai_next) {
if (rp->ai_family == AF_INET || rp->ai_family == AF_INET6) {
swl = xmalloc(sizeof(struct sockaddr_with_len));
- swl->socklen = rp->ai_addrlen;
memcpy(&swl->sock_u.sock, rp->ai_addr, rp->ai_addrlen);
break;
}
@@ -136,7 +131,6 @@ sockaddr_with_len *get_sockaddr(char *host, int port, sa_family_t af)
freeaddrinfo(result);
if (!rp) error_exit("bad host name");
-
if(swl->sock_u.sock.sa_family == AF_INET)
swl->sock_u.sock_in.sin_port = port_num;
else if(swl->sock_u.sock.sa_family == AF_INET6)
@@ -145,39 +139,6 @@ sockaddr_with_len *get_sockaddr(char *host, int port, sa_family_t af)
return swl;
}
-/*
- * get the numeric hostname and service name, for a given socket address.
- */
-char *address_to_name(struct sockaddr *sock)
-{
- //man page of getnameinfo.
- char hbuf[NI_MAXHOST] = {0,}, sbuf[NI_MAXSERV] = {0,};
- int status = 0;
-
- if(sock->sa_family == AF_INET) {
- socklen_t len = sizeof(struct sockaddr_in);
- if((status = getnameinfo(sock, len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
- return xmsprintf("%s:%s", hbuf, sbuf);
- else {
- fprintf(stderr, "getnameinfo: %s\n", gai_strerror(status));
- return NULL;
- }
- } else if(sock->sa_family == AF_INET6) {
- socklen_t len = sizeof(struct sockaddr_in6);
- if((status = getnameinfo(sock, len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0) {
- //verification for resolved hostname.
- if(strchr(hbuf, ':')) return xmsprintf("[%s]:%s", hbuf, sbuf);
- else return xmsprintf("%s:%s", hbuf, sbuf);
- } else {
- fprintf(stderr, "getnameinfo: %s\n", gai_strerror(status));
- return NULL;
- }
- } else if(sock->sa_family == AF_UNIX) {
- struct sockaddr_un *sockun = (void*)sock;
- return xmsprintf("local:%.*s", (int) sizeof(sockun->sun_path), sockun->sun_path);
- } else return NULL;
-}
-
static void set_address(char *host_name, struct ifreq *ifre, int request)
{
struct sockaddr_in *sock_in = (struct sockaddr_in *)&ifre->ifr_addr;
@@ -196,27 +157,9 @@ static void set_address(char *host_name, struct ifreq *ifre, int request)
xioctl(TT.sockfd, request, ifre);
}
-static void add_iface_to_list(struct if_list *newnode)
-{
- struct if_list *head_ref = TT.if_list;
-
- if(!head_ref || strcmp(newnode->name, head_ref->name) < 0) {
- newnode->next = head_ref;
- head_ref = newnode;
- } else {
- struct if_list *current = head_ref;
- while(current->next && strcmp(current->next->name, newnode->name) < 0)
- current = current->next;
- newnode->next = current->next;
- current->next = newnode;
- }
- TT.if_list = (void *)head_ref;
-}
-
-static void get_device_info(struct if_list *il)
+static void get_device_info(char *name, struct if_list *il)
{
struct ifreq ifre;
- char *name = il->name;
il->txqueuelen = -1;
@@ -247,7 +190,7 @@ static void get_device_info(struct if_list *il)
il->netmask = ifre.ifr_netmask;
}
-static void display_ifconfig(struct if_list *il)
+static void display_ifconfig(char *name, struct if_list *il)
{
struct {
int type;
@@ -264,7 +207,7 @@ static void display_ifconfig(struct if_list *il)
for (i=0; i < (sizeof(types)/sizeof(*types))-1; i++)
if (il->hw_type == types[i].type) break;
- xprintf("%-9s Link encap:%s ", il->name, types[i].title);
+ xprintf("%-9s Link encap:%s ", name, types[i].title);
if(il->hwaddr.sa_data && il->hw_type == ARPHRD_ETHER) {
xprintf("HWaddr ");
for (i=0; i<6; i++) xprintf(":%02X"+!i, il->hwaddr.sa_data[i]);
@@ -303,18 +246,18 @@ static void display_ifconfig(struct if_list *il)
fp = fopen("/proc/net/if_net6", "r");
if (fp) {
char iface_name[IFNAMSIZ] = {0,};
- int plen, scope;
+ int plen, iscope;
while(fgets(toybuf, sizeof(toybuf), fp)) {
int nitems = 0;
char ipv6_addr[40] = {0,};
nitems = sscanf(toybuf, "%32s %*08x %02x %02x %*02x %15s\n",
- ipv6_addr+7, &plen, &scope, iface_name);
+ ipv6_addr+7, &plen, &iscope, iface_name);
if(nitems != 4) {
if((nitems < 0) && feof(fp)) break;
perror_exit("sscanf");
}
- if(strcmp(il->name, iface_name) == 0) {
+ if(strcmp(name, iface_name) == 0) {
int i = 0;
struct sockaddr_in6 sock_in6;
int len = sizeof(ipv6_addr) / (sizeof ipv6_addr[0]);
@@ -329,13 +272,13 @@ static void display_ifconfig(struct if_list *il)
if(inet_pton(AF_INET6, ipv6_addr, (struct sockaddr *) &sock_in6.sin6_addr) > 0) {
sock_in6.sin6_family = AF_INET6;
if(inet_ntop(AF_INET6, &sock_in6.sin6_addr, toybuf, BUFSIZ)) {
- char *names[] = {"Global","Host","Link","Site","Compat"},
- *name = "Unknown";
+ char *scopes[] = {"Global","Host","Link","Site","Compat"},
+ *scope = "Unknown";
int j;
- for (j=0; j < sizeof(names)/sizeof(*names); j++)
- if (scope == (!!j)<<(j+3)) name = names[j];
- xprintf("%10cinet6 addr: %s/%d Scope: %s\n", ' ', toybuf, plen, name);
+ for (j=0; j < sizeof(scopes)/sizeof(*scopes); j++)
+ if (iscope == (!!j)<<(j+3)) scope = scopes[j];
+ xprintf("%10cinet6 addr: %s/%d Scope: %s\n", ' ', toybuf, plen, scope);
}
}
}
@@ -393,92 +336,86 @@ static void display_ifconfig(struct if_list *il)
xputc('\n');
}
-static void readconf(void)
-{
- struct ifconf ifcon;
- struct ifreq *ifre;
- int num;
-
- // Loop until buffer's big enough
- ifcon.ifc_buf = NULL;
- for (num = 30;;num += 10) {
- ifcon.ifc_len = sizeof(struct ifreq)*num;
- ifcon.ifc_buf = xrealloc(ifcon.ifc_buf, ifcon.ifc_len);
- xioctl(TT.sockfd, SIOCGIFCONF, &ifcon);
- if (ifcon.ifc_len != sizeof(struct ifreq)*num) break;
- }
-
- ifre = ifcon.ifc_req;
- for(num = 0; num < ifcon.ifc_len && ifre; num += sizeof(struct ifreq), ifre++)
- {
- struct if_list *il;
-
- // Skip duplicates
- for(il = TT.if_list; il; il = il->next)
- if(!strcmp(ifre->ifr_name, il->name)) break;
- if(!il) {
- il = xzalloc(sizeof(struct if_list));
- xstrncpy(il->name, ifre->ifr_name, IFNAMSIZ);
- add_iface_to_list(il);
- get_device_info(il);
- }
- }
-
- free(ifcon.ifc_buf);
-}
-
static void show_iface(char *iface_name)
{
- struct if_list *il;
+ char *name;
+ struct if_list il;
+ struct string_list *ifaces = 0, *sl;
int i, j;
FILE *fp;
fp = xfopen("/proc/net/dev", "r");
for (i=0; fgets(toybuf, sizeof(toybuf), fp); i++) {
- char *name, *buf;
+ char *buf = toybuf;
if (i<2) continue;
- il = xzalloc(sizeof(struct if_list));
- for (buf = toybuf; isspace(*buf); buf++);
+ while (isspace(*buf)) buf++;
name = strsep(&buf, ":");
if(!buf) error_exit("bad name %s", name);
- xstrncpy(il->name, name, IFNAMSIZ);
errno = 0;
- for (j=0; j<16 && !errno; j++) il->val[j] = strtoll(buf, &buf, 0);
+ for (j=0; j<16 && !errno; j++) il.val[j] = strtoll(buf, &buf, 0);
if (errno) perror_exit("bad %s at %s", name, buf);
- add_iface_to_list(il);
- il->non_virtual_iface = 1;
- get_device_info(il);
+ il.non_virtual_iface = 1;
+
+ if (iface_name) {
+ if (!strcmp(iface_name, name)) {
+ get_device_info(name, &il);
+ display_ifconfig(name, &il);
+
+ return;
+ }
+ } else {
+ sl = xmalloc(sizeof(*sl)+strlen(name)+1);
+ strcpy(sl->str, name);
+ sl->next = ifaces;
+ ifaces = sl;
+
+ get_device_info(name, &il);
+ if ((il.flags & IFF_UP) || (toys.optflags & FLAG_a))
+ display_ifconfig(name, &il);
+ }
}
fclose(fp);
if (iface_name) {
- for(il = TT.if_list; il; il = il->next) {
- if(!strcmp(il->name, iface_name)) {
- display_ifconfig(il);
- break;
- }
+ get_device_info(iface_name, &il);
+ display_ifconfig(iface_name, &il);
+ } else {
+ struct ifconf ifcon;
+ struct ifreq *ifre;
+ int num;
+
+ // Loop until buffer's big enough
+ ifcon.ifc_buf = NULL;
+ for (num = 30;;num += 10) {
+ ifcon.ifc_len = sizeof(struct ifreq)*num;
+ ifcon.ifc_buf = xrealloc(ifcon.ifc_buf, ifcon.ifc_len);
+ xioctl(TT.sockfd, SIOCGIFCONF, &ifcon);
+ if (ifcon.ifc_len != sizeof(struct ifreq)*num) break;
}
- //if the given interface is not in the list.
- if(!il) {
- il = xzalloc(sizeof(struct if_list));
- xstrncpy(il->name, iface_name, IFNAMSIZ);
- get_device_info(il);
- display_ifconfig(il);
- free(il);
+
+ ifre = ifcon.ifc_req;
+ for(num = 0; num < ifcon.ifc_len && ifre; num += sizeof(struct ifreq), ifre++)
+ {
+ // Skip duplicates
+ 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);
+ }
}
- } else {
- readconf();
- for(il = TT.if_list; il; il = il->next)
- if((il->flags & IFF_UP) || (toys.optflags & FLAG_a))
- display_ifconfig(il);
+
+ free(ifcon.ifc_buf);
}
- if (CFG_TOYBOX_FREE) llist_traverse(TT.if_list, free);
+ llist_traverse(ifaces, free);
}
// Encode offset and size of field into an int, and make result negative