From d8c437feadcf82b0a6f5ba0654e2e38da2a59150 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Wed, 7 Oct 2015 10:33:59 -0400 Subject: adding --mtu option --- src/firejail/firejail.h | 7 ++-- src/firejail/main.c | 21 ++++++++++-- src/firejail/network.c | 82 +++++++++++++++++++++++++++++++++++++++++++-- src/firejail/network_main.c | 2 +- src/firejail/sandbox.c | 12 +++---- todo | 2 ++ 6 files changed, 111 insertions(+), 15 deletions(-) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 09631be7a..261821338 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -40,6 +40,7 @@ typedef struct bridge_t { uint32_t ip; // interface device IP address uint32_t mask; // interface device mask uint8_t mac[6]; // interface mac address + int mtu; // interface mtu // inside the sandbox char *devsandbox; // name of the device inside the sandbox @@ -60,7 +61,7 @@ typedef struct interface_t { uint32_t ip; uint32_t mask; uint8_t mac[6]; - // todo: add mtu + int mtu; uint8_t configured; } Interface; @@ -195,8 +196,8 @@ void net_dns_print(pid_t pid); // network.c void net_if_up(const char *ifname); -void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask); -int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]); +void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu); +int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu); int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw); void net_ifprint(void); void net_bridge_add_interface(const char *bridge, const char *dev); diff --git a/src/firejail/main.c b/src/firejail/main.c index ea04ea73f..a7eda3906 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -822,7 +822,7 @@ int main(int argc, char **argv) { if (!intf->dev) errExit("strdup"); - if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac)) { + if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac, &intf->mtu)) { fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev); } intf->configured = 1; @@ -917,6 +917,22 @@ int main(int argc, char **argv) { return 1; } } + else if (strncmp(argv[i], "--mtu=", 6) == 0) { + Bridge *br = last_bridge_configured(); + if (br == NULL) { + fprintf(stderr, "Error: no network device configured\n"); + return 1; + } + if (br->mtu) { + fprintf(stderr, "Error: cannot configure mtu twice for the same interface\n"); + return 1; + } + + if (sscanf(argv[i] + 6, "%d", &br->mtu) != 1 || br->mtu < 68 || br->mtu > 9198) { + fprintf(stderr, "Error: invalid mtu value\n"); + return 1; + } + } else if (strncmp(argv[i], "--ip=", 5) == 0) { Bridge *br = last_bridge_configured(); if (br == NULL) { @@ -1231,8 +1247,9 @@ int main(int argc, char **argv) { if (!arg_nonetwork) { // create veth pair or macvlan device if (cfg.bridge0.configured) { - if (cfg.bridge0.macvlan == 0) + if (cfg.bridge0.macvlan == 0) { net_configure_veth_pair(&cfg.bridge0, "eth0", child); + } else net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child); } diff --git a/src/firejail/network.c b/src/firejail/network.c index 888db938c..5469bbcd1 100644 --- a/src/firejail/network.c +++ b/src/firejail/network.c @@ -93,12 +93,63 @@ void net_ifprint(void) { freeifaddrs(ifaddr); } +int net_get_mtu(const char *ifname) { + int mtu = 0; + if (strlen(ifname) > IFNAMSIZ) { + fprintf(stderr, "Error: invalid network device name %s\n", ifname); + exit(1); + } + + int s; + struct ifreq ifr; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + errExit("socket"); + + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) == 0) + mtu = ifr.ifr_mtu; + if (arg_debug) + printf("MTU of %s is %d.\n", ifname, ifr.ifr_mtu); + close(s); + + + return mtu; +} + +void net_set_mtu(const char *ifname, int mtu) { + if (strlen(ifname) > IFNAMSIZ) { + fprintf(stderr, "Error: invalid network device name %s\n", ifname); + exit(1); + } + + if (arg_debug) + printf("set interface %s MTU %d.\n", ifname, mtu); + + int s; + struct ifreq ifr; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + errExit("socket"); + + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_mtu = mtu; + if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) == 0) + mtu = ifr.ifr_mtu; + close(s); +} // return -1 if the interface was not found; if the interface was found retrn 0 and fill in IP address and mask -int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]) { +int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu) { assert(bridge); assert(ip); assert(mask); + + if (arg_debug) + printf("get interface %s configuration\n", bridge); + int rv = -1; struct ifaddrs *ifaddr, *ifa; @@ -117,8 +168,10 @@ int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t ma *mask = ntohl(si->sin_addr.s_addr); si = (struct sockaddr_in *) ifa->ifa_addr; *ip = ntohl(si->sin_addr.s_addr); - if (strcmp(ifa->ifa_name, "lo") != 0) + if (strcmp(ifa->ifa_name, "lo") != 0) { net_get_mac(ifa->ifa_name, mac); + *mtu = net_get_mtu(bridge); + } rv = 0; break; @@ -186,11 +239,13 @@ void net_if_up(const char *ifname) { } // configure interface -void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask) { +void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) { if (strlen(ifname) > IFNAMSIZ) { fprintf(stderr, "Error: invalid network device name %s\n", ifname); exit(1); } + if (arg_debug) + printf("configure interface %s\n", ifname); int sock = socket(AF_INET,SOCK_DGRAM,0); if (sock < 0) @@ -214,6 +269,15 @@ void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask) { errExit("ioctl"); } } + + // configure mtu + if (mtu > 0) { + ifr.ifr_mtu = mtu; + if (ioctl( sock, SIOCSIFMTU, &ifr ) < 0) { + close(sock); + errExit("ioctl"); + } + } close(sock); usleep(10000); // sleep 10ms @@ -264,6 +328,11 @@ void net_bridge_add_interface(const char *bridge, const char *dev) { exit(1); } + // somehow adding the interface to the bridge resets MTU on bridge device!!! + // workaround: restore MTU on the bridge device + // todo: put a real fix in + int mtu1 = net_get_mtu(bridge); + struct ifreq ifr; int err; int ifindex = if_nametoindex(dev); @@ -290,6 +359,13 @@ void net_bridge_add_interface(const char *bridge, const char *dev) { } (void) err; close(sock); + + int mtu2 = net_get_mtu(bridge); + if (mtu1 != mtu2) { + if (arg_debug) + printf("Restoring MTU for %s\n", bridge); + net_set_mtu(bridge, mtu1); + } } #define BUFSIZE 1024 diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c index 21d11ff38..e9de84400 100644 --- a/src/firejail/network_main.c +++ b/src/firejail/network_main.c @@ -56,7 +56,7 @@ void net_configure_bridge(Bridge *br, char *dev_name) { } } - if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac)) { + if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) { fprintf(stderr, "Error: interface %s is not configured\n", br->dev); exit(1); } diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index ddfcc8404..c9146560b 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -84,7 +84,7 @@ static void sandbox_if_up(Bridge *br) { assert(br->ipsandbox); if (arg_debug) printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); - net_if_ip(dev, br->ipsandbox, br->mask); + net_if_ip(dev, br->ipsandbox, br->mask, br->mtu); net_if_up(dev); } else if (br->arg_ip_none == 0 && br->macvlan == 1) { @@ -107,7 +107,7 @@ static void sandbox_if_up(Bridge *br) { if (arg_debug) printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); - net_if_ip(dev, br->ipsandbox, br->mask); + net_if_ip(dev, br->ipsandbox, br->mask, br->mtu); net_if_up(dev); } } @@ -308,25 +308,25 @@ int sandbox(void* sandbox_arg) { if (cfg.interface0.configured && cfg.interface0.ip) { if (arg_debug) printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev); - net_if_ip(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask); + net_if_ip(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu); net_if_up(cfg.interface0.dev); } if (cfg.interface1.configured && cfg.interface1.ip) { if (arg_debug) printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev); - net_if_ip(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask); + net_if_ip(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu); net_if_up(cfg.interface1.dev); } if (cfg.interface2.configured && cfg.interface2.ip) { if (arg_debug) printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev); - net_if_ip(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask); + net_if_ip(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu); net_if_up(cfg.interface2.dev); } if (cfg.interface3.configured && cfg.interface3.ip) { if (arg_debug) printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev); - net_if_ip(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask); + net_if_ip(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu); net_if_up(cfg.interface3.dev); } diff --git a/todo b/todo index 3e329f3c4..b2c98014c 100644 --- a/todo +++ b/todo @@ -43,3 +43,5 @@ make[1]: *** [seccomp.o] Error 1 6. Debian 32bit - multiple problems with the testing utility +7. Add IRC clients: KVIrc (KDE), BitchX (CLI), Smuxi, Konversation (KDE), HexChat, Irssi (CLI), WeeChat (CLI) +RSS: Liferea, akregator (KDE), newsbeuter (CLI), rawdog, -- cgit v1.2.3-70-g09d2