diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2023-04-27 17:30:09 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2023-04-27 17:30:09 +0200 |
commit | 54f8b58fc17b278596f4def1b690e719913c2e75 (patch) | |
tree | 4c8717b2d63ab85dc3c5c503105f2682a0f5b398 | |
parent | fa9d42260a789bebec1fee6fe3a19a0695617600 (diff) | |
download | abase-54f8b58fc17b278596f4def1b690e719913c2e75.tar.gz abase-54f8b58fc17b278596f4def1b690e719913c2e75.tar.bz2 |
implemented printing and up/down of simple interfaces
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | ifconfig.c | 200 |
2 files changed, 200 insertions, 4 deletions
@@ -8,7 +8,9 @@ Currently it contains the following: - a simple 'hexdump' - a 'fdisk' (but we have to decide for which kind of partition types and what kind of operations, could be too big) -- a 'ifconfig' +- a 'ifconfig': show and configure simple interfaces +- a 'ping': test a network connection +- a 'netstat': see list of active connections of a machine Note: abase is a shameless copy of sbase/ubase in certain areas like the Makefile, libutil, etc. This might also make an integration into @@ -1,26 +1,203 @@ /* See LICENSE file for copyright and license details. */ +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <arpa/inet.h> #include <net/if.h> #include <stdio.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> #include "util.h" static void usage(void) { - eprintf("usage: %s [-a]\n", argv0); + eprintf("usage: %s [-a] [<interface>] [up|down]\n", argv0); } +#ifndef IFF_LOWER_UP +#define IFF_LOWER_UP 1<<16 +#endif +#ifndef IFF_DORMANT +#define IFF_DORMANT 1<<17 +#endif +#ifndef IFF_ECHO +#define IFF_ECHO 1<<18 +#endif + static void print_interface(char *name) { - printf("%s\n", name); + int fd; + struct ifreq ifr; + int first; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + weprintf("error in socket(AF_INTER, SOCK_DGRAM, 0) on interface '%s': %s\n", name, strerror(errno)); + return; + } + + strncpy(ifr.ifr_name, name, IF_NAMESIZE); + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + close(fd); + weprintf("error in ioctl(SIOCGIFFLAGS) on interface '%s': %s\n", name, strerror(errno)); + return; + } + + printf("%s: flags=%d<", name, ifr.ifr_flags); + + if (ifr.ifr_flags == 0) { + printf(">"); + } else { + first = 1; + if (ifr.ifr_flags & IFF_UP) { + printf("%sUP", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_BROADCAST) { + printf("%sBROADCAST", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_DEBUG) { + printf("%sDEBUG", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_LOOPBACK) { + printf("%sLOOPBACK", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_POINTOPOINT) { + printf("%sPOINTOPOINT", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_RUNNING) { + printf("%sRUNNING", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_NOARP) { + printf("%sNOARP", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_PROMISC) { + printf("%sPROMISC", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_NOTRAILERS) { + printf("%sNOTRAILERS", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_ALLMULTI) { + printf("%sALLMULTI", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_MASTER) { + printf("%sMASTER", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_SLAVE) { + printf("%sSLAVE", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_MULTICAST) { + printf("%sMULTICAST", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_PORTSEL) { + printf("%sPORTSEL", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_AUTOMEDIA) { + printf("%sAUTOMEDIA", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_DYNAMIC) { + printf("%sDYNAMIC", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_LOWER_UP) { + printf("%sLOWER_UP", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_DORMANT) { + printf("%sDORMANT", !first ? "," : ""); first = 0; + } + if (ifr.ifr_flags & IFF_ECHO) { + printf("%sECHO", !first ? "," : ""); first = 0; + } + printf(">"); + } + + if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { + close(fd); + weprintf("error in ioctl(SIOCGIFMTU) on interface '%s': %s\n", name, strerror(errno)); + return; + } + printf(" mtu %d\n", ifr.ifr_mtu); + + char ip_addr[INET_ADDRSTRLEN]; + if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) { + struct sockaddr_in* addr = (struct sockaddr_in*)&ifr.ifr_addr; + inet_ntop(AF_INET, &addr->sin_addr, ip_addr, INET_ADDRSTRLEN); + } else { + ip_addr[0] = '\0'; + } + + char ip_netmask[INET_ADDRSTRLEN]; + if (ioctl(fd, SIOCGIFNETMASK, &ifr) == 0) { + struct sockaddr_in* netmask = (struct sockaddr_in*)&ifr.ifr_netmask; + inet_ntop(AF_INET, &netmask->sin_addr, ip_netmask, INET_ADDRSTRLEN); + } else { + ip_netmask[0] = '\0'; + } + + char ip_broadcast[INET_ADDRSTRLEN]; + if (ioctl(fd, SIOCGIFBRDADDR, &ifr) == 0) { + struct sockaddr_in* broadcast = (struct sockaddr_in*)&ifr.ifr_broadaddr; + inet_ntop(AF_INET, &broadcast->sin_addr, ip_broadcast, INET_ADDRSTRLEN); + } else { + ip_broadcast[0] = '\0'; + } + + char ip_hwaddr[32]; + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) { + memcpy(ip_hwaddr, ifr.ifr_hwaddr.sa_data, 8); + } else { + memset(ip_hwaddr, 0, 32); + } + + printf(" inet %s netmask %s broadcast %s\n", + ip_addr, ip_netmask, ip_broadcast); + printf(" ether "); + first = 1; + for (int i = 0; i <6; i++) { + printf("%s%02x", ( !first ) ? ":" : "", ip_hwaddr[i] & 0xFF); first = 0; + } + puts(""); + + close(fd); +} + +static void +set_up_down(char *name, int up) +{ + int fd; + struct ifreq ifr; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + weprintf("error in socket(AF_INTER, SOCK_DGRAM, 0) on interface '%s': %s\n", name, strerror(errno)); + return; + } + + strncpy(ifr.ifr_name, name, IF_NAMESIZE); + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + close(fd); + weprintf("error in ioctl(SIOCGIFFLAGS) on interface '%s': %s\n", name, strerror(errno)); + return; + } + + if (up) { + ifr.ifr_flags |= IFF_UP; + } else { + ifr.ifr_flags &= ~IFF_UP; + } + + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + close(fd); + weprintf("error in ioctl(SIOCGIFFLAGS) on interface '%s': %s\n", name, strerror(errno)); + return; + } } int main(int argc, char *argv[]) { int show_all = 0; - //~ struct ifreq ifr; ARGBEGIN { case 'a': @@ -42,5 +219,22 @@ main(int argc, char *argv[]) } } + if (argc == 1) { + print_interface(argv[0]); + } else if (argc == 2) { + int up; + if (strcmp(argv[1], "up") == 0) { + up = 1; + } else if (strcmp(argv[1], "down") == 0) { + up = 0; + } else { + weprintf("Expecting 'up' or 'down'\n"); + usage(); + } + set_up_down(argv[0], up); + } else { + usage(); + } + return 0; } |