All pastes #944759 Raw Edit

Stuff

public c v1 · immutable
·published 2008-03-16 12:02 UTC
rendered paste body
int _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;}