Mercurial > hg > toybox
changeset 1193:f6f56a002d9a draft
Add /prefix netmask support to ifconfig, ala "ifconfig eth0 192.168.1.42/28"
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 04 Feb 2014 06:13:13 -0600 |
parents | 3df4da929f8a |
children | 855b706d10dc |
files | toys/other/ifconfig.c |
diffstat | 1 files changed, 24 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/toys/other/ifconfig.c Sun Feb 02 15:02:15 2014 -0600 +++ b/toys/other/ifconfig.c Tue Feb 04 06:13:13 2014 -0600 @@ -64,16 +64,20 @@ }; // Convert hostname to binary address for AF_INET or AF_INET6 -void get_addrinfo(char *host, sa_family_t af, void *addr) +// return /prefix (or range max if none) +int get_addrinfo(char *host, sa_family_t af, void *addr) { struct addrinfo hints, *result, *rp = 0; int status, len; - char *from; + char *from, *slash; memset(&hints, 0 , sizeof(struct addrinfo)); hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; + slash = strchr(host, '/'); + if (slash) *slash = 0; + status = getaddrinfo(host, NULL, &hints, &result); if (!status) for (rp = result; rp; rp = rp->ai_next) @@ -89,6 +93,11 @@ } else len = 4; memcpy(addr, from, len); freeaddrinfo(result); + + len = -1; + if (slash) len = atolx_range(slash+1, 0, (af == AF_INET) ? 128 : 32); + + return len; } static void display_ifconfig(char *name, int always, unsigned long long val[]) @@ -443,21 +452,15 @@ unsigned prefix; int index; } ifre6; - int plen = 128, fd6 = xsocket(AF_INET6, SOCK_DGRAM, 0); - char *prefix; + int plen, fd6 = xsocket(AF_INET6, SOCK_DGRAM, 0); if (!argv[1]) { toys.exithelp++; error_exit(*argv); } - prefix = strchr(argv[1], '/'); - if (prefix) { - plen = atolx_range(prefix+1, 0, 128); - *prefix = 0; - } - - get_addrinfo(argv[1], AF_INET6, &ifre6.addr); + plen = get_addrinfo(argv[1], AF_INET6, &ifre6.addr); + if (plen < 0) plen = 128; xioctl(fd6, SIOCGIFINDEX, &ifre); ifre6.index = ifre.ifr_ifindex; ifre6.prefix = plen; @@ -491,12 +494,21 @@ break; } else if (t->name || !strchr(ifre.ifr_name, ':')) { struct sockaddr_in *si = (struct sockaddr_in *)&ifre.ifr_addr; + int mask = -1; si->sin_family = AF_INET; if (!strcmp(*argv, "default")) si->sin_addr.s_addr = INADDR_ANY; - else get_addrinfo(*argv, AF_INET, &si->sin_addr); + else mask = get_addrinfo(*argv, AF_INET, &si->sin_addr); xioctl(TT.sockfd, off, &ifre); + + // Handle /netmask + if (mask >= 0) { + // sin_addr probably isn't unaligned, but just in case... + mask = htonl((~0)<<(32-mask)); + memcpy(&si->sin_addr, &mask, 4); + xioctl(TT.sockfd, SIOCSIFNETMASK, &ifre); + } } } off = 0;