summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2023-04-27 17:30:09 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2023-04-27 17:30:09 +0200
commit54f8b58fc17b278596f4def1b690e719913c2e75 (patch)
tree4c8717b2d63ab85dc3c5c503105f2682a0f5b398
parentfa9d42260a789bebec1fee6fe3a19a0695617600 (diff)
downloadabase-54f8b58fc17b278596f4def1b690e719913c2e75.tar.gz
abase-54f8b58fc17b278596f4def1b690e719913c2e75.tar.bz2
implemented printing and up/down of simple interfaces
-rw-r--r--README4
-rw-r--r--ifconfig.c200
2 files changed, 200 insertions, 4 deletions
diff --git a/README b/README
index 295c21a..24f0c06 100644
--- a/README
+++ b/README
@@ -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
diff --git a/ifconfig.c b/ifconfig.c
index 2d3b8eb..809be95 100644
--- a/ifconfig.c
+++ b/ifconfig.c
@@ -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;
}