10f66f451Sopenharmony_ci/* tunctl.c - Control tap/tun network devices.
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2016 Rob Landley <rob@landley.net>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * See http://kernel.org/doc/Documentation/networking/tuntap.txt
60f66f451Sopenharmony_ci *
70f66f451Sopenharmony_ci * This is useful for things like "kvm -netdev tap" and containers.
80f66f451Sopenharmony_ci * See https://landley.net/lxc/02-networking.html for example usage.
90f66f451Sopenharmony_ci *
100f66f451Sopenharmony_ci * todo: bridge mode
110f66f451Sopenharmony_ci *  -b	bridge daemon (forwards packets between NAME and NAME2 interfaces)
120f66f451Sopenharmony_ci
130f66f451Sopenharmony_ci
140f66f451Sopenharmony_ciUSE_TUNCTL(NEWTOY(tunctl, "<1>1t|d|u:T[!td]", TOYFLAG_USR|TOYFLAG_BIN))
150f66f451Sopenharmony_ci
160f66f451Sopenharmony_ciconfig TUNCTL
170f66f451Sopenharmony_ci  bool "tunctl"
180f66f451Sopenharmony_ci  default y
190f66f451Sopenharmony_ci  help
200f66f451Sopenharmony_ci    usage: tunctl [-dtT] [-u USER] NAME
210f66f451Sopenharmony_ci
220f66f451Sopenharmony_ci    Create and delete tun/tap virtual ethernet devices.
230f66f451Sopenharmony_ci
240f66f451Sopenharmony_ci    -T	Use tap (ethernet frames) instead of tun (ip packets)
250f66f451Sopenharmony_ci    -d	Delete tun/tap device
260f66f451Sopenharmony_ci    -t	Create tun/tap device
270f66f451Sopenharmony_ci    -u	Set owner (user who can read/write device without root access)
280f66f451Sopenharmony_ci*/
290f66f451Sopenharmony_ci
300f66f451Sopenharmony_ci#define FOR_tunctl
310f66f451Sopenharmony_ci#include "toys.h"
320f66f451Sopenharmony_ci#include <linux/if_tun.h>
330f66f451Sopenharmony_ci
340f66f451Sopenharmony_ciGLOBALS(
350f66f451Sopenharmony_ci  char *u;
360f66f451Sopenharmony_ci)
370f66f451Sopenharmony_ci
380f66f451Sopenharmony_civoid tunctl_main(void)
390f66f451Sopenharmony_ci{
400f66f451Sopenharmony_ci  struct ifreq *ifr = (void *)toybuf;
410f66f451Sopenharmony_ci  uid_t u = TT.u ?  xgetuid(TT.u) : 0;
420f66f451Sopenharmony_ci  int fd = xopen("/dev/net/tun", O_RDWR);
430f66f451Sopenharmony_ci
440f66f451Sopenharmony_ci  // Associate filehandle with device
450f66f451Sopenharmony_ci  ifr->ifr_flags = ((toys.optflags&FLAG_T) ? IFF_TUN : IFF_TAP)|IFF_NO_PI;
460f66f451Sopenharmony_ci  strncpy(ifr->ifr_name, *toys.optargs, sizeof(ifr->ifr_name));
470f66f451Sopenharmony_ci  xioctl(fd, TUNSETIFF, toybuf);
480f66f451Sopenharmony_ci
490f66f451Sopenharmony_ci  if (toys.optflags&FLAG_t) {
500f66f451Sopenharmony_ci    xioctl(fd, TUNSETPERSIST, (void *)1);
510f66f451Sopenharmony_ci    xioctl(fd, TUNSETOWNER, (void *)(long)u);
520f66f451Sopenharmony_ci  } else xioctl(fd, TUNSETPERSIST, (void *)0);
530f66f451Sopenharmony_ci}
54