/* * Copyright (C) 2014-2021 Firejail Authors * * This file is part of firejail project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "firemon.h" #include #include #include #include #include #include #include #include #include #include #include //#include //#include // print IP addresses for all interfaces static void net_ifprint(void) { uint32_t ip; uint32_t mask; struct ifaddrs *ifaddr, *ifa; int fd; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { fprintf(stderr, "Error: cannot open AF_INET socket\n"); exit(1); } if (getifaddrs(&ifaddr) == -1) errExit("getifaddrs"); // walk through the linked list printf(" Link status:\n"); for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) continue; if (ifa->ifa_addr->sa_family == AF_PACKET) { if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP) { if (ifa->ifa_data != NULL) { struct rtnl_link_stats *stats = ifa->ifa_data; // extract mac address struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ - 1); int rv = ioctl (fd, SIOCGIFHWADDR, &ifr); if (rv == 0) printf(" %s UP, %02x:%02x:%02x:%02x:%02x:%02x\n", ifa->ifa_name, PRINT_MAC((unsigned char *) &ifr.ifr_hwaddr.sa_data)); else printf(" %s UP\n", ifa->ifa_name); printf(" tx/rx: %u/%u packets, %u/%u bytes\n", stats->tx_packets, stats->rx_packets, stats->tx_bytes, stats->rx_bytes); } } else printf(" %s DOWN\n", ifa->ifa_name); } } // walk through the linked list printf(" IPv4 status:\n"); for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) continue; if (ifa->ifa_addr->sa_family == AF_INET) { struct sockaddr_in *si = (struct sockaddr_in *) ifa->ifa_netmask; mask = ntohl(si->sin_addr.s_addr); si = (struct sockaddr_in *) ifa->ifa_addr; ip = ntohl(si->sin_addr.s_addr); char *status; if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP) status = "UP"; else status = "DOWN"; printf(" %s %s, %d.%d.%d.%d/%u\n", ifa->ifa_name, status, PRINT_IP(ip), mask2bits(mask)); } } // walk through the linked list printf(" IPv6 status:\n"); for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) continue; if (ifa->ifa_addr->sa_family == AF_INET6) { char host[NI_MAXHOST]; int s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (s == 0) { char *ptr; if ((ptr = strchr(host, '%')) != NULL) *ptr = '\0'; char *status; if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP) status = "UP"; else status = "DOWN"; printf(" %s %s, %s\n", ifa->ifa_name, status, host); } } } freeifaddrs(ifaddr); close(fd); } static void print_sandbox(pid_t pid) { pid_t child = fork(); if (child == -1) return; if (child == 0) { int rv = join_namespace(pid, "net"); if (rv) return; net_ifprint(); #ifdef HAVE_GCOV __gcov_flush(); #endif _exit(0); } // wait for the child to finish waitpid(child, NULL, 0); } void interface(pid_t pid, int print_procs) { pid_read(pid); // a pid of 0 will include all processes // print processes int i; for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) { if (print_procs || pid == 0) pid_print_list(i, arg_wrap); int child = find_child(i); if (child != -1) { print_sandbox(child); } } } printf("\n"); }