tunctl.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * tun devices controller
  4. *
  5. * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
  6. *
  7. * Original code:
  8. * Jeff Dike
  9. *
  10. * Licensed under GPLv2, see file LICENSE in this source tree.
  11. */
  12. #include <netinet/in.h>
  13. #include <net/if.h>
  14. #include <linux/if_tun.h>
  15. #include "libbb.h"
  16. /* TUNSETGROUP appeared in 2.6.23 */
  17. #ifndef TUNSETGROUP
  18. #define TUNSETGROUP _IOW('T', 206, int)
  19. #endif
  20. #define IOCTL(a, b, c) ioctl_or_perror_and_die(a, b, c, NULL)
  21. #if 1
  22. int tunctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  23. int tunctl_main(int argc UNUSED_PARAM, char **argv)
  24. {
  25. struct ifreq ifr;
  26. int fd;
  27. const char *opt_name = "tap%d";
  28. const char *opt_device = "/dev/net/tun";
  29. #if ENABLE_FEATURE_TUNCTL_UG
  30. const char *opt_user, *opt_group;
  31. long user = -1, group = -1;
  32. #endif
  33. unsigned opts;
  34. enum {
  35. OPT_f = 1 << 0, // control device name (/dev/net/tun)
  36. OPT_t = 1 << 1, // create named interface
  37. OPT_d = 1 << 2, // delete named interface
  38. #if ENABLE_FEATURE_TUNCTL_UG
  39. OPT_u = 1 << 3, // set new interface owner
  40. OPT_g = 1 << 4, // set new interface group
  41. OPT_b = 1 << 5, // brief output
  42. #endif
  43. };
  44. opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d
  45. opts = getopt32(argv, "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b"),
  46. &opt_device, &opt_name, &opt_name
  47. IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group));
  48. // select device
  49. memset(&ifr, 0, sizeof(ifr));
  50. ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  51. strncpy_IFNAMSIZ(ifr.ifr_name, opt_name);
  52. // open device
  53. fd = xopen(opt_device, O_RDWR);
  54. IOCTL(fd, TUNSETIFF, (void *)&ifr);
  55. // delete?
  56. if (opts & OPT_d) {
  57. IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0);
  58. bb_info_msg("Set '%s' %spersistent", ifr.ifr_name, "non");
  59. return EXIT_SUCCESS;
  60. }
  61. // create
  62. #if ENABLE_FEATURE_TUNCTL_UG
  63. if (opts & OPT_g) {
  64. group = xgroup2gid(opt_group);
  65. IOCTL(fd, TUNSETGROUP, (void *)(uintptr_t)group);
  66. } else
  67. user = geteuid();
  68. if (opts & OPT_u)
  69. user = xuname2uid(opt_user);
  70. IOCTL(fd, TUNSETOWNER, (void *)(uintptr_t)user);
  71. #endif
  72. IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)1);
  73. // show info
  74. #if ENABLE_FEATURE_TUNCTL_UG
  75. if (opts & OPT_b) {
  76. puts(ifr.ifr_name);
  77. } else {
  78. printf("Set '%s' %spersistent", ifr.ifr_name, "");
  79. printf(" and owned by uid %ld", user);
  80. if (group != -1)
  81. printf(" gid %ld", group);
  82. bb_putchar('\n');
  83. }
  84. #else
  85. puts(ifr.ifr_name);
  86. #endif
  87. return EXIT_SUCCESS;
  88. }
  89. #else
  90. /* -210 bytes: */
  91. int tunctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  92. int tunctl_main(int argc UNUSED_PARAM, char **argv)
  93. {
  94. struct ifreq ifr;
  95. int fd;
  96. const char *opt_name = "tap%d";
  97. const char *opt_device = "/dev/net/tun";
  98. unsigned opts;
  99. enum {
  100. OPT_f = 1 << 0, // control device name (/dev/net/tun)
  101. OPT_t = 1 << 1, // create named interface
  102. OPT_d = 1 << 2, // delete named interface
  103. };
  104. opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d
  105. opts = getopt32(argv, "f:t:d:u:g:b", // u, g, b accepted and ignored
  106. &opt_device, &opt_name, &opt_name, NULL, NULL);
  107. // set interface name
  108. memset(&ifr, 0, sizeof(ifr));
  109. ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  110. strncpy_IFNAMSIZ(ifr.ifr_name, opt_name);
  111. // open device
  112. fd = xopen(opt_device, O_RDWR);
  113. IOCTL(fd, TUNSETIFF, (void *)&ifr);
  114. // create or delete interface
  115. IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)(0 == (opts & OPT_d)));
  116. return EXIT_SUCCESS;
  117. }
  118. #endif