rendered paste bodyint _tunnel_create_device(tunnel * tun) { struct ifreq ifr; struct ifreq ifrq; int fd; int s; struct sockaddr_in *sin; if((fd = open("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0) { return -1; } memset(&ifr, 0, sizeof(ifr)); //ifr.ifr_flags = IFF_TUN | IFF_NO_PI; ifr.ifr_flags = IFF_TUN | IFF_NO_PI; if(tun->dev[0] != 0) { strncpy(ifr.ifr_name, tun->dev, IFNAMSIZ); } if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { if (errno == EBADFD) { /* Try old ioctl */ //if (ioctl(fd, OTUNSETIFF, (void *) &ifr) < 0) { close(fd); return -1; //} } else { close(fd); return -1; } } tun->local_fd = fd; strcpy(tun->dev, ifr.ifr_name); log_message(LOG_LEVEL_DEBUG, "Device %s opened", tun->dev); tun->local_fd = fd; return 0;}// Creates the tunnelint tunnel_create(tunnel * tun, int socket_fd, SSL* ssl) { int opt; // Configure device (tun->local_fd) if(_tunnel_create_device(tun) < 0) { log_message(LOG_LEVEL_ERROR, "Can't open the device"); return -1; } // Configure output socket (tun->remote_fd) tun->remote_fd = socket_fd; tun->ssl = ssl; opt=1; setsockopt(tun->remote_fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); opt=1; setsockopt(tun->remote_fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); // Set IPs to the tunnel //run_command(TRUE, "ifconfig", "%s %s pointopoint %s mtu 1450", tun->dev, tun->local_tun_ip, tun->remote_tun_ip); //run_command(TRUE, "ifconfig", "%s 192.168.1.25 pointopoint 192.168.1.42 mtu 1450", tun->dev); //run_command(TRUE, "ip", "tunnel add %s mode ipip local 192.168.1.25 remote 192.168.1.26", tun->dev); return 0;}int _tunnel_read_local (tunnel * tun, char * buf, int len) { return read(tun->local_fd, buf, len);}int _tunnel_write_local (tunnel * tun, char * buf, int len) { return write(tun->local_fd, buf, len);}int _tunnel_read_remote (tunnel * tun, char * buf, int len) { //return read(tun->remote_fd, buf, len); return SSL_read(tun->ssl, buf, len);}int _tunnel_write_remote (tunnel * tun, char * buf, int len) { //return write(tun->remote_fd, buf, len); return SSL_write(tun->ssl, buf, len);}int tunnel_process(tunnel * tun) { fd_set fdset; int max_fd; char * buf; int length, fds; int fd1, fd2; struct timeval tv; fd1 = tun->local_fd; fd2 = tun->remote_fd; FD_ZERO(&fdset); FD_SET(fd1, &fdset); FD_SET(fd2, &fdset); max_fd = (fd1 > fd2 ? fd1 : fd2) + 1; log_message(LOG_LEVEL_DEBUG, "Local device FD: %d", fd1); log_message(LOG_LEVEL_DEBUG, "Remote socket FD: %d", fd2); log_message(LOG_LEVEL_DEBUG, "Max FD: %d", max_fd); buf = (char *) malloc(TUNNEL_BUFFER_LENGTH * sizeof(char)); tv.tv_sec=5; while(TRUE) { if((fds = select(max_fd, &fdset, NULL, NULL, NULL)) > 0) { log_message(LOG_LEVEL_DEBUG, "Data on %d file descriptors", fds); // Someone has written on our device if(FD_ISSET(fd1, &fdset)) { memset(buf, 0, TUNNEL_BUFFER_LENGTH); length = _tunnel_read_local(tun, buf, TUNNEL_BUFFER_LENGTH); log_message(LOG_LEVEL_DEBUG, "Data on device (length = %d)", length); if(length > 0) { if(_tunnel_write_remote(tun, buf, length) != length) { log_message(LOG_LEVEL_ERROR, "Can't write on socket: (%d) %s", errno, strerror(errno)); return -1; } } else { log_message(LOG_LEVEL_ERROR, "Wrong data entry on device: (%d) %s", errno, strerror(errno)); return -1; } } // The peer has written on the socket_fd if(FD_ISSET(fd2, &fdset)) { memset(buf, 0, TUNNEL_BUFFER_LENGTH); length = _tunnel_read_remote(tun, buf, TUNNEL_BUFFER_LENGTH); log_message(LOG_LEVEL_DEBUG, "Data on socket (length = %d)", length); if(length > 0) { if(_tunnel_write_local(tun, buf, length) != length) { log_message(LOG_LEVEL_ERROR, "Can't write on device: (%d) %s", errno, strerror(errno)); return -1; } } else { log_message(LOG_LEVEL_ERROR, "Wrong data entry on socket: (%d) %s", errno, strerror(errno)); return -1; } } } } free(buf); return 0;}