You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tunctl.c 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* Copyright 2002 Jeff Dike
  2. * Licensed under the GPL
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. #include <pwd.h>
  11. #include <net/if.h>
  12. #include <sys/ioctl.h>
  13. #include <linux/if_tun.h>
  14. static void Usage(char *name)
  15. {
  16. fprintf(stderr, "Create: %s [-b] [-u owner] [-t device-name] "
  17. "[-f tun-clone-device]\n", name);
  18. fprintf(stderr, "Delete: %s -d device-name [-f tun-clone-device]\n\n",
  19. name);
  20. fprintf(stderr, "The default tun clone device is /dev/net/tun - some systems"
  21. " use\n/dev/misc/net/tun instead\n\n");
  22. fprintf(stderr, "-b will result in brief output (just the device name)\n");
  23. exit(1);
  24. }
  25. int main(int argc, char **argv)
  26. {
  27. struct ifreq ifr;
  28. struct passwd *pw;
  29. long owner = geteuid();
  30. int tap_fd, opt, delete = 0, brief = 0;
  31. char *tun = "", *file = "/dev/net/tun", *name = argv[0], *end;
  32. while((opt = getopt(argc, argv, "bd:f:t:u:")) > 0){
  33. switch(opt) {
  34. case 'b':
  35. brief = 1;
  36. break;
  37. case 'd':
  38. delete = 1;
  39. tun = optarg;
  40. break;
  41. case 'f':
  42. file = optarg;
  43. break;
  44. case 'u':
  45. pw = getpwnam(optarg);
  46. if(pw != NULL){
  47. owner = pw->pw_uid;
  48. break;
  49. }
  50. owner = strtol(optarg, &end, 0);
  51. if(*end != '\0'){
  52. fprintf(stderr, "'%s' is neither a username nor a numeric uid.\n",
  53. optarg);
  54. Usage(name);
  55. }
  56. break;
  57. case 't':
  58. tun = optarg;
  59. break;
  60. case 'h':
  61. default:
  62. Usage(name);
  63. }
  64. }
  65. argv += optind;
  66. argc -= optind;
  67. if(argc > 0)
  68. Usage(name);
  69. if((tap_fd = open(file, O_RDWR)) < 0){
  70. fprintf(stderr, "Failed to open '%s' : ", file);
  71. perror("");
  72. exit(1);
  73. }
  74. memset(&ifr, 0, sizeof(ifr));
  75. ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  76. strncpy(ifr.ifr_name, tun, sizeof(ifr.ifr_name) - 1);
  77. if(ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0){
  78. perror("TUNSETIFF");
  79. exit(1);
  80. }
  81. if(delete){
  82. if(ioctl(tap_fd, TUNSETPERSIST, 0) < 0){
  83. perror("TUNSETPERSIST");
  84. exit(1);
  85. }
  86. printf("Set '%s' nonpersistent\n", ifr.ifr_name);
  87. }
  88. else {
  89. if(ioctl(tap_fd, TUNSETPERSIST, 1) < 0){
  90. perror("TUNSETPERSIST");
  91. exit(1);
  92. }
  93. if(ioctl(tap_fd, TUNSETOWNER, owner) < 0){
  94. perror("TUNSETPERSIST");
  95. exit(1);
  96. }
  97. if(brief)
  98. printf("%s\n", ifr.ifr_name);
  99. else printf("Set '%s' persistent and owned by uid %ld\n", ifr.ifr_name,
  100. owner);
  101. }
  102. return(0);
  103. }