+int
+tun_open(int tun, int mode)
+{
+#if defined(CUSTOM_SYS_TUN_OPEN)
+ return (sys_tun_open(tun, mode));
+#elif defined(SSH_TUN_OPENBSD)
+ struct ifreq ifr;
+ char name[100];
+ int fd = -1, sock;
+
+ /* Open the tunnel device */
+ if (tun <= SSH_TUNID_MAX) {
+ snprintf(name, sizeof(name), "/dev/tun%d", tun);
+ fd = open(name, O_RDWR);
+ } else if (tun == SSH_TUNID_ANY) {
+ for (tun = 100; tun >= 0; tun--) {
+ snprintf(name, sizeof(name), "/dev/tun%d", tun);
+ if ((fd = open(name, O_RDWR)) >= 0)
+ break;
+ }
+ } else {
+ debug("%s: invalid tunnel %u", __func__, tun);
+ return (-1);
+ }
+
+ if (fd < 0) {
+ debug("%s: %s open failed: %s", __func__, name, strerror(errno));
+ return (-1);
+ }
+
+ debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
+
+ /* Set the tunnel device operation mode */
+ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun);
+ if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
+ goto failed;
+
+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
+ goto failed;
+
+ /* Set interface mode */
+ ifr.ifr_flags &= ~IFF_UP;
+ if (mode == SSH_TUNMODE_ETHERNET)
+ ifr.ifr_flags |= IFF_LINK0;
+ else
+ ifr.ifr_flags &= ~IFF_LINK0;
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
+ goto failed;
+
+ /* Bring interface up */
+ ifr.ifr_flags |= IFF_UP;
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
+ goto failed;
+
+ close(sock);
+ return (fd);
+
+ failed:
+ if (fd >= 0)
+ close(fd);
+ if (sock >= 0)
+ close(sock);
+ debug("%s: failed to set %s mode %d: %s", __func__, name,
+ mode, strerror(errno));
+ return (-1);
+#else
+ error("Tunnel interfaces are not supported on this platform");
+ return (-1);
+#endif
+}
+
+void
+sanitise_stdfd(void)
+{
+ int nullfd, dupfd;
+
+ if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
+ fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
+ exit(1);
+ }
+ while (++dupfd <= 2) {
+ /* Only clobber closed fds */
+ if (fcntl(dupfd, F_GETFL, 0) >= 0)
+ continue;
+ if (dup2(nullfd, dupfd) == -1) {
+ fprintf(stderr, "dup2: %s", strerror(errno));
+ exit(1);
+ }
+ }
+ if (nullfd > 2)
+ close(nullfd);
+}
+