diff options
author | netblue30 <netblue30@yahoo.com> | 2015-10-07 10:33:59 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2015-10-07 10:33:59 -0400 |
commit | d8c437feadcf82b0a6f5ba0654e2e38da2a59150 (patch) | |
tree | 8a1cf81b6a6d47ac479b16e01a07f0c7eb1bb6f2 /src/firejail/network.c | |
parent | main page (diff) | |
download | firejail-d8c437feadcf82b0a6f5ba0654e2e38da2a59150.tar.gz firejail-d8c437feadcf82b0a6f5ba0654e2e38da2a59150.tar.zst firejail-d8c437feadcf82b0a6f5ba0654e2e38da2a59150.zip |
adding --mtu option
Diffstat (limited to 'src/firejail/network.c')
-rw-r--r-- | src/firejail/network.c | 82 |
1 files changed, 79 insertions, 3 deletions
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) { | |||
93 | freeifaddrs(ifaddr); | 93 | freeifaddrs(ifaddr); |
94 | } | 94 | } |
95 | 95 | ||
96 | int net_get_mtu(const char *ifname) { | ||
97 | int mtu = 0; | ||
98 | if (strlen(ifname) > IFNAMSIZ) { | ||
99 | fprintf(stderr, "Error: invalid network device name %s\n", ifname); | ||
100 | exit(1); | ||
101 | } | ||
102 | |||
103 | int s; | ||
104 | struct ifreq ifr; | ||
105 | |||
106 | if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) | ||
107 | errExit("socket"); | ||
108 | |||
109 | ifr.ifr_addr.sa_family = AF_INET; | ||
110 | strncpy(ifr.ifr_name, ifname, IFNAMSIZ); | ||
111 | if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) == 0) | ||
112 | mtu = ifr.ifr_mtu; | ||
113 | if (arg_debug) | ||
114 | printf("MTU of %s is %d.\n", ifname, ifr.ifr_mtu); | ||
115 | close(s); | ||
116 | |||
117 | |||
118 | return mtu; | ||
119 | } | ||
120 | |||
121 | void net_set_mtu(const char *ifname, int mtu) { | ||
122 | if (strlen(ifname) > IFNAMSIZ) { | ||
123 | fprintf(stderr, "Error: invalid network device name %s\n", ifname); | ||
124 | exit(1); | ||
125 | } | ||
126 | |||
127 | if (arg_debug) | ||
128 | printf("set interface %s MTU %d.\n", ifname, mtu); | ||
129 | |||
130 | int s; | ||
131 | struct ifreq ifr; | ||
132 | |||
133 | if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) | ||
134 | errExit("socket"); | ||
135 | |||
136 | ifr.ifr_addr.sa_family = AF_INET; | ||
137 | strncpy(ifr.ifr_name, ifname, IFNAMSIZ); | ||
138 | ifr.ifr_mtu = mtu; | ||
139 | if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) == 0) | ||
140 | mtu = ifr.ifr_mtu; | ||
141 | close(s); | ||
142 | } | ||
96 | 143 | ||
97 | // return -1 if the interface was not found; if the interface was found retrn 0 and fill in IP address and mask | 144 | // return -1 if the interface was not found; if the interface was found retrn 0 and fill in IP address and mask |
98 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]) { | 145 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu) { |
99 | assert(bridge); | 146 | assert(bridge); |
100 | assert(ip); | 147 | assert(ip); |
101 | assert(mask); | 148 | assert(mask); |
149 | |||
150 | if (arg_debug) | ||
151 | printf("get interface %s configuration\n", bridge); | ||
152 | |||
102 | int rv = -1; | 153 | int rv = -1; |
103 | struct ifaddrs *ifaddr, *ifa; | 154 | struct ifaddrs *ifaddr, *ifa; |
104 | 155 | ||
@@ -117,8 +168,10 @@ int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t ma | |||
117 | *mask = ntohl(si->sin_addr.s_addr); | 168 | *mask = ntohl(si->sin_addr.s_addr); |
118 | si = (struct sockaddr_in *) ifa->ifa_addr; | 169 | si = (struct sockaddr_in *) ifa->ifa_addr; |
119 | *ip = ntohl(si->sin_addr.s_addr); | 170 | *ip = ntohl(si->sin_addr.s_addr); |
120 | if (strcmp(ifa->ifa_name, "lo") != 0) | 171 | if (strcmp(ifa->ifa_name, "lo") != 0) { |
121 | net_get_mac(ifa->ifa_name, mac); | 172 | net_get_mac(ifa->ifa_name, mac); |
173 | *mtu = net_get_mtu(bridge); | ||
174 | } | ||
122 | 175 | ||
123 | rv = 0; | 176 | rv = 0; |
124 | break; | 177 | break; |
@@ -186,11 +239,13 @@ void net_if_up(const char *ifname) { | |||
186 | } | 239 | } |
187 | 240 | ||
188 | // configure interface | 241 | // configure interface |
189 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask) { | 242 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) { |
190 | if (strlen(ifname) > IFNAMSIZ) { | 243 | if (strlen(ifname) > IFNAMSIZ) { |
191 | fprintf(stderr, "Error: invalid network device name %s\n", ifname); | 244 | fprintf(stderr, "Error: invalid network device name %s\n", ifname); |
192 | exit(1); | 245 | exit(1); |
193 | } | 246 | } |
247 | if (arg_debug) | ||
248 | printf("configure interface %s\n", ifname); | ||
194 | 249 | ||
195 | int sock = socket(AF_INET,SOCK_DGRAM,0); | 250 | int sock = socket(AF_INET,SOCK_DGRAM,0); |
196 | if (sock < 0) | 251 | if (sock < 0) |
@@ -214,6 +269,15 @@ void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask) { | |||
214 | errExit("ioctl"); | 269 | errExit("ioctl"); |
215 | } | 270 | } |
216 | } | 271 | } |
272 | |||
273 | // configure mtu | ||
274 | if (mtu > 0) { | ||
275 | ifr.ifr_mtu = mtu; | ||
276 | if (ioctl( sock, SIOCSIFMTU, &ifr ) < 0) { | ||
277 | close(sock); | ||
278 | errExit("ioctl"); | ||
279 | } | ||
280 | } | ||
217 | 281 | ||
218 | close(sock); | 282 | close(sock); |
219 | usleep(10000); // sleep 10ms | 283 | usleep(10000); // sleep 10ms |
@@ -264,6 +328,11 @@ void net_bridge_add_interface(const char *bridge, const char *dev) { | |||
264 | exit(1); | 328 | exit(1); |
265 | } | 329 | } |
266 | 330 | ||
331 | // somehow adding the interface to the bridge resets MTU on bridge device!!! | ||
332 | // workaround: restore MTU on the bridge device | ||
333 | // todo: put a real fix in | ||
334 | int mtu1 = net_get_mtu(bridge); | ||
335 | |||
267 | struct ifreq ifr; | 336 | struct ifreq ifr; |
268 | int err; | 337 | int err; |
269 | int ifindex = if_nametoindex(dev); | 338 | int ifindex = if_nametoindex(dev); |
@@ -290,6 +359,13 @@ void net_bridge_add_interface(const char *bridge, const char *dev) { | |||
290 | } | 359 | } |
291 | (void) err; | 360 | (void) err; |
292 | close(sock); | 361 | close(sock); |
362 | |||
363 | int mtu2 = net_get_mtu(bridge); | ||
364 | if (mtu1 != mtu2) { | ||
365 | if (arg_debug) | ||
366 | printf("Restoring MTU for %s\n", bridge); | ||
367 | net_set_mtu(bridge, mtu1); | ||
368 | } | ||
293 | } | 369 | } |
294 | 370 | ||
295 | #define BUFSIZE 1024 | 371 | #define BUFSIZE 1024 |