?? tun.c
字號:
tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode){ struct tuntap tt; open_tun (dev, dev_type, dev_node, ipv6, &tt); if (ioctl (tt.fd, TUNSETPERSIST, persist_mode) < 0) msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev); close_tun (&tt); msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));}#endif /* TUNSETPERSIST */#elsevoidopen_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt){ open_tun_generic (dev, dev_node, ipv6, false, tt);}#endif /* HAVE_LINUX_IF_TUN_H */voidclose_tun (struct tuntap *tt){ close_tun_generic (tt);}intwrite_tun (struct tuntap* tt, uint8_t *buf, int len){#if LINUX_IPV6 if (tt->ipv6) { struct tun_pi pi; struct iphdr *iph; struct iovec vect[2]; int ret; iph = (struct iphdr *)buf; pi.flags = 0; if(iph->version == 6) pi.proto = htons(ETH_P_IPV6); else pi.proto = htons(ETH_P_IP); vect[0].iov_len = sizeof(pi); vect[0].iov_base = π vect[1].iov_len = len; vect[1].iov_base = buf; ret = writev(tt->fd, vect, 2); return(ret - sizeof(pi)); } else#endif return write (tt->fd, buf, len);}intread_tun (struct tuntap* tt, uint8_t *buf, int len){#if LINUX_IPV6 if (tt->ipv6) { struct iovec vect[2]; struct tun_pi pi; int ret; vect[0].iov_len = sizeof(pi); vect[0].iov_base = π vect[1].iov_len = len; vect[1].iov_base = buf; ret = readv(tt->fd, vect, 2); return(ret - sizeof(pi)); } else#endif return read (tt->fd, buf, len);}#elif defined(TARGET_SOLARIS)voidopen_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt){ int if_fd, muxid, ppa = -1; struct ifreq ifr; const char *ptr; const char *ip_node; const char *dev_tuntap_type; int link_type; bool is_tun; clear_tuntap (tt); ipv6_support (ipv6, false, tt); if (!strcmp(dev, "null")) { open_null (tt); return; } if (is_dev_type (dev, dev_type, "tun")) { ip_node = "/dev/udp"; if (!dev_node) dev_node = "/dev/tun"; dev_tuntap_type = "tun"; link_type = I_PLINK; is_tun = true; } else if (is_dev_type (dev, dev_type, "tap")) { ip_node = "/dev/ip"; if (!dev_node) dev_node = "/dev/tap"; dev_tuntap_type = "tap"; link_type = I_PLINK; /* was: I_LINK */ is_tun = false; } else { msg (M_FATAL, "I don't recognize device %s as a tun or tap device", dev); } /* get unit number */ if (*dev) { ptr = dev; while (*ptr && !isdigit ((int) *ptr)) ptr++; ppa = atoi (ptr); } if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0) msg (M_ERR, "Can't open %s", ip_node); if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0) msg (M_ERR, "Can't open %s", dev_node); /* Assign a new PPA and get its unit number. */ if ((ppa = ioctl (tt->fd, TUNNEWPPA, ppa)) < 0) msg (M_ERR, "Can't assign new interface"); if ((if_fd = open (dev_node, O_RDWR, 0)) < 0) msg (M_ERR, "Can't open %s (2)", dev_node); if (ioctl (if_fd, I_PUSH, "ip") < 0) msg (M_ERR, "Can't push IP module"); /* Assign ppa according to the unit number returned by tun device */ if (ioctl (if_fd, IF_UNITSEL, (char *) &ppa) < 0) msg (M_ERR, "Can't set PPA %d", ppa); if ((muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0) msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type); close (if_fd); snprintf (tt->actual, sizeof (tt->actual), "%s%d", dev_tuntap_type, ppa); CLEAR (ifr); strncpynt (ifr.ifr_name, tt->actual, sizeof (ifr.ifr_name)); ifr.ifr_ip_muxid = muxid; if (ioctl (tt->ip_fd, SIOCSIFMUXID, &ifr) < 0) { ioctl (tt->ip_fd, I_PUNLINK, muxid); msg (M_ERR, "Can't set multiplexor id"); } set_nonblock (tt->fd);}/* * Close TUN device. */voidclose_tun (struct tuntap* tt){ if (tt->fd >= 0) { struct ifreq ifr; CLEAR (ifr); strncpynt (ifr.ifr_name, tt->actual, sizeof (ifr.ifr_name)); if (ioctl (tt->ip_fd, SIOCGIFFLAGS, &ifr) < 0) msg (M_ERR, "Can't get iface flags"); if (ioctl (tt->ip_fd, SIOCGIFMUXID, &ifr) < 0) msg (M_ERR, "Can't get multiplexor id"); if (ioctl (tt->ip_fd, I_PUNLINK, ifr.ifr_ip_muxid) < 0) msg (M_ERR, "Can't unlink interface"); close (tt->ip_fd); close (tt->fd); } clear_tuntap (tt);}intwrite_tun (struct tuntap* tt, uint8_t *buf, int len){ struct strbuf sbuf; sbuf.len = len; sbuf.buf = buf; return putmsg (tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;}intread_tun (struct tuntap* tt, uint8_t *buf, int len){ struct strbuf sbuf; int f = 0; sbuf.maxlen = len; sbuf.buf = buf; return getmsg (tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;}#elif defined(TARGET_OPENBSD)voidopen_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt){ open_tun_generic (dev, dev_node, ipv6, false, tt);}voidclose_tun (struct tuntap* tt){ close_tun_generic (tt);}static inline intopenbsd_modify_read_write_return (int len){ if (len > 0) return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0; else return len;}intwrite_tun (struct tuntap* tt, uint8_t *buf, int len){ u_int32_t type = htonl (AF_INET); struct iovec iv[2]; iv[0].iov_base = &type; iv[0].iov_len = sizeof (type); iv[1].iov_base = buf; iv[1].iov_len = len; return openbsd_modify_read_write_return (writev (tt->fd, iv, 2));}intread_tun (struct tuntap* tt, uint8_t *buf, int len){ u_int32_t type; struct iovec iv[2]; iv[0].iov_base = &type; iv[0].iov_len = sizeof (type); iv[1].iov_base = buf; iv[1].iov_len = len; return openbsd_modify_read_write_return (readv (tt->fd, iv, 2));}#elif defined(TARGET_FREEBSD)voidopen_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt){ open_tun_generic (dev, dev_node, ipv6, false, tt); if (tt->fd >= 0) { int i = 0; /* Disable extended modes */ ioctl (tt->fd, TUNSLMODE, &i); ioctl (tt->fd, TUNSIFHEAD, &i); }}voidclose_tun (struct tuntap* tt){ close_tun_generic (tt);}intwrite_tun (struct tuntap* tt, uint8_t *buf, int len){ return write (tt->fd, buf, len);}intread_tun (struct tuntap* tt, uint8_t *buf, int len){ return read (tt->fd, buf, len);}#else /* generic */voidopen_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt){ open_tun_generic (dev, dev_node, ipv6, false, tt);}voidclose_tun (struct tuntap* tt){ close_tun_generic (tt);}intwrite_tun (struct tuntap* tt, uint8_t *buf, int len){ return write (tt->fd, buf, len);}intread_tun (struct tuntap* tt, uint8_t *buf, int len){ return read (tt->fd, buf, len);}#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -