device.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /*
  2. device.c -- Interaction BSD tun/tap device
  3. Copyright (C) 2001-2005 Ivo Timmermans,
  4. 2001-2016 Guus Sliepen <guus@tinc-vpn.org>
  5. 2009 Grzegorz Dymarek <gregd72002@googlemail.com>
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License along
  15. with this program; if not, write to the Free Software Foundation, Inc.,
  16. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. #include "../system.h"
  19. #include "../conf.h"
  20. #include "../device.h"
  21. #include "../logger.h"
  22. #include "../net.h"
  23. #include "../route.h"
  24. #include "../utils.h"
  25. #include "../xalloc.h"
  26. #ifdef ENABLE_TUNEMU
  27. #include "tunemu.h"
  28. #endif
  29. #ifdef HAVE_NET_IF_UTUN_H
  30. #include <sys/sys_domain.h>
  31. #include <sys/kern_control.h>
  32. #include <net/if_utun.h>
  33. #endif
  34. #define DEFAULT_TUN_DEVICE "/dev/tun0"
  35. #define DEFAULT_TAP_DEVICE "/dev/tap0"
  36. typedef enum device_type {
  37. DEVICE_TYPE_TUN,
  38. DEVICE_TYPE_TUNIFHEAD,
  39. DEVICE_TYPE_TAP,
  40. #ifdef ENABLE_TUNEMU
  41. DEVICE_TYPE_TUNEMU,
  42. #endif
  43. DEVICE_TYPE_UTUN,
  44. } device_type_t;
  45. int device_fd = -1;
  46. char *device = NULL;
  47. char *iface = NULL;
  48. static const char *device_info = "OS X utun device";
  49. static uint64_t device_total_in = 0;
  50. static uint64_t device_total_out = 0;
  51. #if defined(ENABLE_TUNEMU)
  52. static device_type_t device_type = DEVICE_TYPE_TUNEMU;
  53. #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY)
  54. static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD;
  55. #else
  56. static device_type_t device_type = DEVICE_TYPE_TUN;
  57. #endif
  58. #ifdef HAVE_NET_IF_UTUN_H
  59. static bool setup_utun(void) {
  60. device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
  61. if(device_fd == -1) {
  62. logger(LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno));
  63. return false;
  64. }
  65. struct ctl_info info = {};
  66. strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name));
  67. if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) {
  68. logger(LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno));
  69. return false;
  70. }
  71. int unit = -1;
  72. char *p = strstr(device, "utun"), *e = NULL;
  73. if(p) {
  74. unit = strtol(p + 4, &e, 10);
  75. if(!e) {
  76. unit = -1;
  77. }
  78. }
  79. struct sockaddr_ctl sc = {
  80. .sc_id = info.ctl_id,
  81. .sc_len = sizeof(sc),
  82. .sc_family = AF_SYSTEM,
  83. .ss_sysaddr = AF_SYS_CONTROL,
  84. .sc_unit = unit + 1,
  85. };
  86. if(connect(device_fd, (struct sockaddr *)&sc, sizeof(sc)) == -1) {
  87. logger(LOG_ERR, "Could not connect utun socket: %s\n", strerror(errno));
  88. return false;
  89. }
  90. char name[64] = "";
  91. socklen_t len = sizeof(name);
  92. if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
  93. iface = xstrdup(device);
  94. } else {
  95. iface = xstrdup(name);
  96. }
  97. logger(LOG_INFO, "%s is a %s", device, device_info);
  98. return true;
  99. }
  100. #endif
  101. static bool setup_device(void) {
  102. // Find out which device file to open
  103. if(!get_config_string(lookup_config(config_tree, "Device"), &device)) {
  104. if(routing_mode == RMODE_ROUTER) {
  105. device = xstrdup(DEFAULT_TUN_DEVICE);
  106. } else {
  107. device = xstrdup(DEFAULT_TAP_DEVICE);
  108. }
  109. }
  110. // Find out if it's supposed to be a tun or a tap device
  111. char *type;
  112. if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
  113. if(!strcasecmp(type, "tun"))
  114. /* use default */;
  115. #ifdef ENABLE_TUNEMU
  116. else if(!strcasecmp(type, "tunemu")) {
  117. device_type = DEVICE_TYPE_TUNEMU;
  118. }
  119. #endif
  120. #ifdef HAVE_NET_IF_UTUN_H
  121. else if(!strcasecmp(type, "utun")) {
  122. device_type = DEVICE_TYPE_UTUN;
  123. }
  124. #endif
  125. else if(!strcasecmp(type, "tunnohead")) {
  126. device_type = DEVICE_TYPE_TUN;
  127. } else if(!strcasecmp(type, "tunifhead")) {
  128. device_type = DEVICE_TYPE_TUNIFHEAD;
  129. } else if(!strcasecmp(type, "tap")) {
  130. device_type = DEVICE_TYPE_TAP;
  131. } else {
  132. logger(LOG_ERR, "Unknown device type %s!", type);
  133. return false;
  134. }
  135. } else {
  136. #ifdef HAVE_NET_IF_UTUN_H
  137. if(strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0) {
  138. device_type = DEVICE_TYPE_UTUN;
  139. } else
  140. #endif
  141. if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) {
  142. device_type = DEVICE_TYPE_TAP;
  143. }
  144. }
  145. if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) {
  146. logger(LOG_ERR, "Only tap devices support switch mode!");
  147. return false;
  148. }
  149. // Open the device
  150. switch(device_type) {
  151. #ifdef ENABLE_TUNEMU
  152. case DEVICE_TYPE_TUNEMU: {
  153. char dynamic_name[256] = "";
  154. device_fd = tunemu_open(dynamic_name);
  155. }
  156. break;
  157. #endif
  158. #ifdef HAVE_NET_IF_UTUN_H
  159. case DEVICE_TYPE_UTUN:
  160. return setup_utun();
  161. #endif
  162. default:
  163. device_fd = open(device, O_RDWR | O_NONBLOCK);
  164. }
  165. if(device_fd < 0) {
  166. logger(LOG_ERR, "Could not open %s: %s", device, strerror(errno));
  167. return false;
  168. }
  169. #ifdef FD_CLOEXEC
  170. fcntl(device_fd, F_SETFD, FD_CLOEXEC);
  171. #endif
  172. // Guess what the corresponding interface is called
  173. char *realname = NULL;
  174. #if defined(HAVE_FDEVNAME)
  175. realname = fdevname(device_fd);
  176. #elif defined(HAVE_DEVNAME)
  177. struct stat buf;
  178. if(!fstat(device_fd, &buf)) {
  179. realname = devname(buf.st_rdev, S_IFCHR);
  180. }
  181. #endif
  182. if(!realname) {
  183. realname = device;
  184. }
  185. if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) {
  186. iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname);
  187. } else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) {
  188. logger(LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly.");
  189. }
  190. // Configure the device as best as we can
  191. switch(device_type) {
  192. default:
  193. device_type = DEVICE_TYPE_TUN;
  194. case DEVICE_TYPE_TUN:
  195. #ifdef TUNSIFHEAD
  196. {
  197. const int zero = 0;
  198. if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) {
  199. logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
  200. return false;
  201. }
  202. }
  203. #endif
  204. #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
  205. {
  206. const int mode = IFF_BROADCAST | IFF_MULTICAST;
  207. ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
  208. }
  209. #endif
  210. device_info = "Generic BSD tun device";
  211. break;
  212. case DEVICE_TYPE_TUNIFHEAD:
  213. #ifdef TUNSIFHEAD
  214. {
  215. const int one = 1;
  216. if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) {
  217. logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
  218. return false;
  219. }
  220. }
  221. #endif
  222. #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
  223. {
  224. const int mode = IFF_BROADCAST | IFF_MULTICAST;
  225. ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
  226. }
  227. #endif
  228. device_info = "Generic BSD tun device";
  229. break;
  230. case DEVICE_TYPE_TAP:
  231. if(routing_mode == RMODE_ROUTER) {
  232. overwrite_mac = true;
  233. }
  234. device_info = "Generic BSD tap device";
  235. #ifdef TAPGIFNAME
  236. {
  237. struct ifreq ifr;
  238. if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) {
  239. if(iface) {
  240. free(iface);
  241. }
  242. iface = xstrdup(ifr.ifr_name);
  243. }
  244. }
  245. #endif
  246. break;
  247. #ifdef ENABLE_TUNEMU
  248. case DEVICE_TYPE_TUNEMU:
  249. device_info = "BSD tunemu device";
  250. break;
  251. #endif
  252. }
  253. #ifdef SIOCGIFADDR
  254. if(overwrite_mac) {
  255. ioctl(device_fd, SIOCGIFADDR, mymac.x);
  256. }
  257. #endif
  258. logger(LOG_INFO, "%s is a %s", device, device_info);
  259. return true;
  260. }
  261. static void close_device(void) {
  262. switch(device_type) {
  263. #ifdef ENABLE_TUNEMU
  264. case DEVICE_TYPE_TUNEMU:
  265. tunemu_close(device_fd);
  266. break;
  267. #endif
  268. default:
  269. close(device_fd);
  270. }
  271. free(device);
  272. free(iface);
  273. }
  274. static bool read_packet(vpn_packet_t *packet) {
  275. int lenin;
  276. switch(device_type) {
  277. case DEVICE_TYPE_TUN:
  278. #ifdef ENABLE_TUNEMU
  279. case DEVICE_TYPE_TUNEMU:
  280. if(device_type == DEVICE_TYPE_TUNEMU) {
  281. lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14);
  282. } else
  283. #endif
  284. lenin = read(device_fd, packet->data + 14, MTU - 14);
  285. if(lenin <= 0) {
  286. logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
  287. device, strerror(errno));
  288. return false;
  289. }
  290. switch(packet->data[14] >> 4) {
  291. case 4:
  292. packet->data[12] = 0x08;
  293. packet->data[13] = 0x00;
  294. break;
  295. case 6:
  296. packet->data[12] = 0x86;
  297. packet->data[13] = 0xDD;
  298. break;
  299. default:
  300. ifdebug(TRAFFIC) logger(LOG_ERR,
  301. "Unknown IP version %d while reading packet from %s %s",
  302. packet->data[14] >> 4, device_info, device);
  303. return false;
  304. }
  305. memset(packet->data, 0, 12);
  306. packet->len = lenin + 14;
  307. break;
  308. case DEVICE_TYPE_UTUN:
  309. case DEVICE_TYPE_TUNIFHEAD: {
  310. if((lenin = read(device_fd, packet->data + 10, MTU - 10)) <= 0) {
  311. logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
  312. device, strerror(errno));
  313. return false;
  314. }
  315. switch(packet->data[14] >> 4) {
  316. case 4:
  317. packet->data[12] = 0x08;
  318. packet->data[13] = 0x00;
  319. break;
  320. case 6:
  321. packet->data[12] = 0x86;
  322. packet->data[13] = 0xDD;
  323. break;
  324. default:
  325. ifdebug(TRAFFIC) logger(LOG_ERR,
  326. "Unknown IP version %d while reading packet from %s %s",
  327. packet->data[14] >> 4, device_info, device);
  328. return false;
  329. }
  330. memset(packet->data, 0, 12);
  331. packet->len = lenin + 10;
  332. break;
  333. }
  334. case DEVICE_TYPE_TAP:
  335. if((lenin = read(device_fd, packet->data, MTU)) <= 0) {
  336. logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
  337. device, strerror(errno));
  338. return false;
  339. }
  340. packet->len = lenin;
  341. break;
  342. default:
  343. return false;
  344. }
  345. device_total_in += packet->len;
  346. ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s",
  347. packet->len, device_info);
  348. return true;
  349. }
  350. static bool write_packet(vpn_packet_t *packet) {
  351. ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
  352. packet->len, device_info);
  353. switch(device_type) {
  354. case DEVICE_TYPE_TUN:
  355. if(write(device_fd, packet->data + 14, packet->len - 14) < 0) {
  356. logger(LOG_ERR, "Error while writing to %s %s: %s", device_info,
  357. device, strerror(errno));
  358. return false;
  359. }
  360. break;
  361. case DEVICE_TYPE_UTUN:
  362. case DEVICE_TYPE_TUNIFHEAD: {
  363. int af = (packet->data[12] << 8) + packet->data[13];
  364. uint32_t type;
  365. switch(af) {
  366. case 0x0800:
  367. type = htonl(AF_INET);
  368. break;
  369. case 0x86DD:
  370. type = htonl(AF_INET6);
  371. break;
  372. default:
  373. ifdebug(TRAFFIC) logger(LOG_ERR,
  374. "Unknown address family %x while writing packet to %s %s",
  375. af, device_info, device);
  376. return false;
  377. }
  378. memcpy(packet->data + 10, &type, sizeof(type));
  379. if(write(device_fd, packet->data + 10, packet->len - 10) < 0) {
  380. logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device,
  381. strerror(errno));
  382. return false;
  383. }
  384. break;
  385. }
  386. case DEVICE_TYPE_TAP:
  387. if(write(device_fd, packet->data, packet->len) < 0) {
  388. logger(LOG_ERR, "Error while writing to %s %s: %s", device_info,
  389. device, strerror(errno));
  390. return false;
  391. }
  392. break;
  393. #ifdef ENABLE_TUNEMU
  394. case DEVICE_TYPE_TUNEMU:
  395. if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) {
  396. logger(LOG_ERR, "Error while writing to %s %s: %s", device_info,
  397. device, strerror(errno));
  398. return false;
  399. }
  400. break;
  401. #endif
  402. default:
  403. return false;
  404. }
  405. device_total_out += packet->len;
  406. return true;
  407. }
  408. static void dump_device_stats(void) {
  409. logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
  410. logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in);
  411. logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
  412. }
  413. const devops_t os_devops = {
  414. .setup = setup_device,
  415. .close = close_device,
  416. .read = read_packet,
  417. .write = write_packet,
  418. .dump_stats = dump_device_stats,
  419. };