aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/network.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-01-11 19:52:15 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2016-01-11 19:52:15 -0500
commite669dbee639c4956430bc90345e1f05687c9d50a (patch)
tree233d0ffca44049d9940f60f35bac74eb3e5db723 /src/firejail/network.c
parentfixed minimum mtu (diff)
downloadfirejail-e669dbee639c4956430bc90345e1f05687c9d50a.tar.gz
firejail-e669dbee639c4956430bc90345e1f05687c9d50a.tar.zst
firejail-e669dbee639c4956430bc90345e1f05687c9d50a.zip
IPv6 support
Diffstat (limited to 'src/firejail/network.c')
-rw-r--r--src/firejail/network.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/src/firejail/network.c b/src/firejail/network.c
index ece406fc8..72bc5e7c6 100644
--- a/src/firejail/network.c
+++ b/src/firejail/network.c
@@ -274,7 +274,75 @@ void net_if_down(const char *ifname) {
274 close(sock); 274 close(sock);
275} 275}
276 276
277// configure interface 277struct ifreq6 {
278 struct in6_addr ifr6_addr;
279 uint32_t ifr6_prefixlen;
280 unsigned int ifr6_ifindex;
281};
282// configure interface ipv6 address
283// ex: firejail --net=eth0 --ip6=2001:0db8:0:f101::1/64
284void net_if_ip6(const char *ifname, const char *addr6) {
285 if (strchr(addr6, ':') == NULL) {
286 fprintf(stderr, "Error: invalid IPv6 address %s\n", addr6);
287 exit(1);
288 }
289
290 // extract prefix
291 unsigned long prefix;
292 char *ptr;
293 if ((ptr = strchr(addr6, '/'))) {
294 prefix = atol(ptr + 1);
295 if ((prefix < 0) || (prefix > 128)) {
296 fprintf(stderr, "Error: invalid prefix for IPv6 address %s\n", addr6);
297 exit(1);
298 }
299 *ptr = '\0'; // mark the end of the address
300 }
301 else
302 prefix = 128;
303
304 // extract address
305 struct sockaddr_in6 sin6;
306 memset(&sin6, 0, sizeof(sin6));
307 sin6.sin6_family = AF_INET6;
308 int rv = inet_pton(AF_INET6, addr6, sin6.sin6_addr.s6_addr);
309 if (rv <= 0) {
310 fprintf(stderr, "Error: invalid IPv6 address %s\n", addr6);
311 exit(1);
312 }
313
314 // open socket
315 int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
316 if (sock < 0) {
317 fprintf(stderr, "Error: IPv6 is not supported on this system\n");
318 exit(1);
319 }
320
321 // find interface index
322 struct ifreq ifr;
323 memset(&ifr, 0, sizeof(ifr));
324 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
325 ifr.ifr_addr.sa_family = AF_INET;
326 if (ioctl(sock, SIOGIFINDEX, &ifr) < 0) {
327 perror("ioctl SIOGIFINDEX");
328 exit(1);
329 }
330
331 // configure address
332 struct ifreq6 ifr6;
333 memset(&ifr6, 0, sizeof(ifr6));
334 ifr6.ifr6_prefixlen = prefix;
335 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
336 memcpy((char *) &ifr6.ifr6_addr, (char *) &sin6.sin6_addr, sizeof(struct in6_addr));
337 if (ioctl(sock, SIOCSIFADDR, &ifr6) < 0) {
338 perror("ioctl SIOCSIFADDR");
339 exit(1);
340 }
341
342 close(sock);
343}
344
345// configure interface ipv4 address
278void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) { 346void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) {
279 if (strlen(ifname) > IFNAMSIZ) { 347 if (strlen(ifname) > IFNAMSIZ) {
280 fprintf(stderr, "Error: invalid network device name %s\n", ifname); 348 fprintf(stderr, "Error: invalid network device name %s\n", ifname);