Example #1
0
File: tap.c Project: pacepi/tapip
void set_tap(void)
{
    skfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (skfd < 0)
        perrx("socket PF_INET");
    skfd6 = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
    if (skfd6 < 0)
        perrx("socket PF_INET6");
}
Example #2
0
/* Lock Init */
static _inline void arp_cache_lock_init(void)
{
#ifndef STATIC_MUTEX
	/* It is evil to init pthread mutex dynamically X< */
	pthread_mutexattr_t attr;
	if (pthread_mutexattr_init(&attr) != 0)
		perrx("pthread_mutexattr_init");
	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL) != 0)
		perrx("pthread_mutexattr_settype");
	if (pthread_mutex_init(&arp_cache_mutex, &attr) != 0)
		perrx("pthread_mutex_init");
#endif
}
Example #3
0
void *xzalloc(size_t size)
{
	void *p = calloc(1,size);
	if(!p)
		perrx("calloc");
	return p;
}
Example #4
0
File: tap.c Project: pacepi/tapip
void getname_tap(int tapfd, unsigned char *name)
{
    struct ifreq ifr = {};
    if (ioctl(tapfd, TUNGETIFF, (void *)&ifr) < 0)
        perrx("ioctl SIOCGIFHWADDR");
    strcpy((char *)name, ifr.ifr_name);
    dbg("net device: %s", name);
}
Example #5
0
void *xmalloc(size_t size)
{
	void *p = malloc(size);
	if(!p) 
		perrx("xmalloc");
	return p;
	       
		
}
Example #6
0
File: tap.c Project: pacepi/tapip
void gethwaddr_tap(int tapfd, unsigned char *ha)
{
    struct ifreq ifr;
    memset(&ifr, 0x0, sizeof(ifr));
    /* get net order hardware address */
    if (ioctl(tapfd, SIOCGIFHWADDR, (void *)&ifr) < 0)
        perrx("ioctl SIOCGIFHWADDR");
    hwacpy(ha, ifr.ifr_hwaddr.sa_data);
    dbg("mac addr: %02x:%02x:%02x:%02x:%02x:%02x",
        ha[0], ha[1], ha[2], ha[3], ha[4], ha[5]);
}
Example #7
0
File: tap.c Project: pacepi/tapip
void setflags_tap(unsigned char *name, unsigned short flags, int set)
{
    struct ifreq ifr = {};

    strcpy(ifr.ifr_name, (char *)name);
    /* get original flags */
    if (ioctl(skfd, SIOCGIFFLAGS, (void *)&ifr) < 0) {
        close(skfd);
        perrx("socket SIOCGIFFLAGS");
    }
    /* set new flags */
    if (set)
        ifr.ifr_flags |= flags;
    else
        ifr.ifr_flags &= ~flags & 0xffff;
    if (ioctl(skfd, SIOCSIFFLAGS, (void *)&ifr) < 0) {
        close(skfd);
        perrx("socket SIOCGIFFLAGS");
    }
}
Example #8
0
File: tap.c Project: pacepi/tapip
void getmtu_tap(unsigned char *name, int *mtu)
{
    struct ifreq ifr = {};

    strcpy(ifr.ifr_name, (char *)name);
    /* get net order hardware address */
    if (ioctl(skfd6, SIOCGIFMTU, (void *)&ifr) < 0) {
        close(skfd6);
        perrx("ioctl SIOCGIFHWADDR");
    }
    *mtu = ifr.ifr_mtu;
    dbg("mtu: %d", ifr.ifr_mtu);
}
Example #9
0
File: tap.c Project: pacepi/tapip
void getipaddr_tap(unsigned char *name, unsigned int *ipaddr)
{
    struct ifreq ifr = {};
    struct sockaddr_in *saddr;

    strcpy(ifr.ifr_name, (char *)name);
    if (ioctl(skfd, SIOCGIFADDR, (void *)&ifr) < 0) {
        close(skfd);
        perrx("socket SIOCGIFADDR");
    }
    saddr = (struct sockaddr_in *)&ifr.ifr_addr;
    *ipaddr = saddr->sin_addr.s_addr;
    dbg("get IPaddr: "IPFMT, ipfmt(*ipaddr));
}
Example #10
0
File: tap.c Project: pacepi/tapip
void setnetmask_tap(unsigned char *name, unsigned int netmask)
{
    struct ifreq ifr = {};
    struct sockaddr_in *saddr;

    strcpy(ifr.ifr_name, (char *)name);
    saddr = (struct sockaddr_in *)&ifr.ifr_netmask;
    saddr->sin_family = AF_INET;
    saddr->sin_addr.s_addr = netmask;
    if (ioctl(skfd, SIOCSIFNETMASK, (void *)&ifr) < 0) {
        close(skfd);
        perrx("socket SIOCSIFNETMASK");
    }
    dbg("set Netmask: "IPFMT, ipfmt(netmask));
}
Example #11
0
File: tap.c Project: pacepi/tapip
void setipaddr_tap(unsigned char *name, unsigned int ipaddr)
{
    struct ifreq ifr = {};
    struct sockaddr_in *saddr;

    strcpy(ifr.ifr_name, (char *)name);
    saddr = (struct sockaddr_in *)&ifr.ifr_addr;
    saddr->sin_family = AF_INET;
    saddr->sin_addr.s_addr = ipaddr;
    if (ioctl(skfd, SIOCSIFADDR, (void *)&ifr) < 0) {
        close(skfd);
        perrx("socket SIOCSIFADDR");
    }
    dbg("set IPaddr: "IPFMT, ipfmt(ipaddr));
}
Example #12
0
File: veth.c Project: 0xcc/tapip
static int veth_dev_init(struct netdev *dev)
{
	/* init tap: out network nic */
	if (tap_dev_init() < 0)
		perrx("Cannot init tap device");

	/* init veth: information for our netstack */
	dev->net_mtu = tap->dev.net_mtu;
	dev->net_ipaddr = FAKE_IPADDR;
	dev->net_mask = FAKE_NETMASK;
	hwacpy(dev->net_hwaddr, FAKE_HWADDR);
	dbg("%s ip address: " IPFMT, dev->net_name, ipfmt(dev->net_ipaddr));
	dbg("%s hw address: " MACFMT, dev->net_name, macfmt(dev->net_hwaddr));
	/* net stats have been zero */
	return 0;
}
Example #13
0
File: veth.c Project: 0xcc/tapip
void veth_poll(void)
{
	struct pollfd pfd = {};
	int ret;
	while (1) {
		pfd.fd = tap->fd;
		pfd.events = POLLIN;
		pfd.revents = 0;
		/* one event, infinite time */
		ret = poll(&pfd, 1, -1);
		if (ret <= 0)
			perrx("poll /dev/net/tun");
		/* get a packet and handle it */
		veth_rx();
	}
}
Example #14
0
/* cr_load_certs : loads private key and certificates from files 
 * if cert_file and key_file are NULL , the function will generate
 * a dynamic certificate and private key
 */
void cr_load_certs(SSL_CTX *ssl,u_char *cert_file,u_char *key_file)
{
	X509 *cert = NULL;
	EVP_PKEY *pkey = NULL;
	
	if(cert_file == NULL || key_file == NULL) {
		/* generate a public certificate and a private key */
		
		cr_make_cert(&cert,&pkey,2048,0,365);

		SSL_CTX_use_certificate(ssl, cert);
		SSL_CTX_use_PrivateKey(ssl, pkey);

#ifdef CR_MK_CERT	
		RSA_print_fp(stdout,pkey->pkey.rsa,0);
		X509_print_fp(stdout,cert);
		
		PEM_write_PrivateKey(stdout,pkey,NULL,NULL,0,NULL, NULL);
		PEM_write_X509(stdout,cert);
#endif

	} else {
		if (SSL_CTX_use_certificate_file(ssl, (const char*)cert_file,
						 SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			exit(3);
		}
		if (SSL_CTX_use_RSAPrivateKey_file(ssl, (const char*)key_file,
						SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			exit(4);
		}
	}
	
	if (!SSL_CTX_check_private_key(ssl)) {
		perrx("Private key does not match the certificate public key\n");
		exit(5);
	}
	
}
Example #15
0
int main(int argc,char **argv)
{
	struct netdev *nd;
	int ret;
	struct socket *sock;

	
	if(argc != 4)
		banner(argv[0]);

	ret = -1;
	nd = xzalloc(sizeof(struct netdev));
	if(!nd) {
		perrx("Couldn't create netdev structure");
		goto bad;
	}
	
	sock = socket_alloc();
	if(sock == NULL)
		goto bad;

	nd->nd_ipaddr = inet_addr(argv[3]);
	nd->nd_ops = &nd_ops;
	
	if(cl_sock_connect(&sock,argv[1],atoi(argv[2])) < 0)
		goto bad;
	
	nd->nd_ipaddr = inet_addr(argv[3]);
	nd->nd_ops = &nd_ops;
	nd->sk = sock;
	if(cl_setup_promisc(nd) < 0)
		goto bad;
	
	
	return 0;
bad:
	if(sock)
		free(sock);
	return ret;
}
Example #16
0
static void
run_file(const char *filename, uid_t uid, gid_t gid)
{
/* Run a file by spawning off a process which redirects I/O,
 * spawns a subshell, then waits for it to complete and sends
 * mail to the user.
 */
    pid_t pid;
    int fd_out, fd_in;
    int queue;
    char mailbuf[LOGNAMESIZE + 1], fmt[49];
    char *mailname = NULL;
    FILE *stream;
    int send_mail = 0;
    struct stat buf, lbuf;
    off_t size;
    struct passwd *pentry;
    int fflags;
    uid_t nuid;
    gid_t ngid;
#ifdef PAM
    pam_handle_t *pamh = NULL;
    int pam_err;
    struct pam_conv pamc = {
	.conv = openpam_nullconv,
	.appdata_ptr = NULL
    };
#endif

    PRIV_START

    if (chmod(filename, S_IRUSR) != 0)
    {
	perr("cannot change file permissions");
    }

    PRIV_END

    pid = fork();
    if (pid == -1)
	perr("cannot fork");
    
    else if (pid != 0)
	return;

    /* Let's see who we mail to.  Hopefully, we can read it from
     * the command file; if not, send it to the owner, or, failing that,
     * to root.
     */

    pentry = getpwuid(uid);
    if (pentry == NULL)
	perrx("Userid %lu not found - aborting job %s",
		(unsigned long) uid, filename);

#ifdef PAM
    PRIV_START

    pam_err = pam_start(atrun, pentry->pw_name, &pamc, &pamh);
    if (pam_err != PAM_SUCCESS)
	perrx("cannot start PAM: %s", pam_strerror(pamh, pam_err));

    pam_err = pam_acct_mgmt(pamh, PAM_SILENT);
    /* Expired password shouldn't prevent the job from running. */
    if (pam_err != PAM_SUCCESS && pam_err != PAM_NEW_AUTHTOK_REQD)
	perrx("Account %s (userid %lu) unavailable for job %s: %s",
	    pentry->pw_name, (unsigned long)uid,
	    filename, pam_strerror(pamh, pam_err));

    pam_end(pamh, pam_err);

    PRIV_END
#endif /* PAM */

    PRIV_START

    stream=fopen(filename, "r");

    PRIV_END

    if (stream == NULL)
	perr("cannot open input file");

    if ((fd_in = dup(fileno(stream))) <0)
	perr("error duplicating input file descriptor");

    if (fstat(fd_in, &buf) == -1)
	perr("error in fstat of input file descriptor");

    if (lstat(filename, &lbuf) == -1)
	perr("error in fstat of input file");

    if (S_ISLNK(lbuf.st_mode))
	perrx("Symbolic link encountered in job %s - aborting", filename);

    if ((lbuf.st_dev != buf.st_dev) || (lbuf.st_ino != buf.st_ino) ||
        (lbuf.st_uid != buf.st_uid) || (lbuf.st_gid != buf.st_gid) ||
        (lbuf.st_size!=buf.st_size))
	perrx("Somebody changed files from under us for job %s - aborting",
		filename);

    if (buf.st_nlink > 1)
	perrx("Somebody is trying to run a linked script for job %s", filename);

    if ((fflags = fcntl(fd_in, F_GETFD)) <0)
	perr("error in fcntl");

    fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);

    snprintf(fmt, sizeof(fmt),
	"#!/bin/sh\n# atrun uid=%%ld gid=%%ld\n# mail %%%ds %%d",
                          LOGNAMESIZE);

    if (fscanf(stream, fmt, &nuid, &ngid, mailbuf, &send_mail) != 4)
	perrx("File %s is in wrong format - aborting", filename);

    if (mailbuf[0] == '-')
	perrx("Illegal mail name %s in %s", mailbuf, filename);

    mailname = mailbuf;

    if (nuid != uid)
	perrx("Job %s - userid %u does not match file uid %u",
		filename, nuid, uid);

    if (ngid != gid)
	perrx("Job %s - groupid %u does not match file gid %u",
		filename, ngid, gid);

    fclose(stream);

    if (chdir(ATSPOOL_DIR) < 0)
	perr("cannot chdir to %s", ATSPOOL_DIR);
    
    /* Create a file to hold the output of the job we are about to run.
     * Write the mail header.
     */    
    if((fd_out=open(filename,
		O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR)) < 0)
	perr("cannot create output file");

    write_string(fd_out, "Subject: Output from your job ");
    write_string(fd_out, filename);
    write_string(fd_out, "\n\n");
    fstat(fd_out, &buf);
    size = buf.st_size;

    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
 
    pid = fork();
    if (pid < 0)
	perr("error in fork");

    else if (pid == 0)
    {
	char *nul = NULL;
	char **nenvp = &nul;

	/* Set up things for the child; we want standard input from the input file,
	 * and standard output and error sent to our output file.
	 */

	if (lseek(fd_in, (off_t) 0, SEEK_SET) < 0)
	    perr("error in lseek");

	if (dup(fd_in) != STDIN_FILENO)
	    perr("error in I/O redirection");

	if (dup(fd_out) != STDOUT_FILENO)
	    perr("error in I/O redirection");

	if (dup(fd_out) != STDERR_FILENO)
	    perr("error in I/O redirection");

	close(fd_in);
	close(fd_out);
	if (chdir(ATJOB_DIR) < 0)
	    perr("cannot chdir to %s", ATJOB_DIR);

	queue = *filename;

	PRIV_START

        nice(tolower(queue) - 'a');
	
#ifdef LOGIN_CAP
	/*
	 * For simplicity and safety, set all aspects of the user context
	 * except for a selected subset:  Don't set priority, which was
	 * set based on the queue file name according to the tradition.
	 * Don't bother to set environment, including path vars, either
	 * because it will be discarded anyway.  Although the job file
	 * should set umask, preset it here just in case.
	 */
	if (setusercontext(NULL, pentry, uid, LOGIN_SETALL &
		~(LOGIN_SETPRIORITY | LOGIN_SETPATH | LOGIN_SETENV)) != 0)
	    exit(EXIT_FAILURE);	/* setusercontext() logged the error */
#else /* LOGIN_CAP */
	if (initgroups(pentry->pw_name,pentry->pw_gid))
	    perr("cannot init group access list");

	if (setgid(gid) < 0 || setegid(pentry->pw_gid) < 0)
	    perr("cannot change group");

	if (setlogin(pentry->pw_name))
	    perr("cannot set login name");

	if (setuid(uid) < 0 || seteuid(uid) < 0)
	    perr("cannot set user id");
#endif /* LOGIN_CAP */

	if (chdir(pentry->pw_dir))
		chdir("/");

	if(execle("/bin/sh","sh",NULL, nenvp) != 0)
	    perr("exec failed for /bin/sh");

	PRIV_END
    }
Example #17
0
/* cr_make_cert generates a server public/private keys 
 * cert : X509 instance
 * pkey : private key instance
 * bits : RSA key length
 * serial : serial number
 * days : how many days the certificate is valid
 */
int cr_make_cert(X509 **cert,EVP_PKEY **pkey,int bits,int serial,int days)
{
	X509 *x;
	EVP_PKEY *pk;
	RSA *rsa;
	X509_NAME *name = NULL;

	if((pkey == NULL) || (*pkey == NULL)) {
		pk = EVP_PKEY_new();
		if(pk == NULL) {
			perrx("EVP_PKEY_new() failed\n");
			return -1;
		}
	} else 
		pk = *pkey;
	
	if((cert == NULL) || (*cert == NULL)) {
		x = X509_new();
		if ((x == NULL)) {
			perrx("X509_new() failed\n");
			return -1;
		} 
	}else
		x= *cert;
	
	/* generate RSA key */
	rsa = RSA_generate_key(bits,RSA_F4,NULL,NULL);
	if(!EVP_PKEY_assign_RSA(pk, rsa)) {
			perrx("X509_new() failed\n");
			return -1;
	}
	rsa = NULL;

	X509_set_version(x,2);
	ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
	X509_gmtime_adj(X509_get_notBefore(x),0);
	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
	X509_set_pubkey(x,pk);

	name=X509_get_subject_name(x);
	
	X509_NAME_add_entry_by_txt(name,"C",
			MBSTRING_ASC, (const unsigned char *)"UK", -1, -1, 0);

	X509_NAME_add_entry_by_txt(name,"CN",
			MBSTRING_ASC, (const unsigned char*)"VPNPivot", -1, -1, 0);
	
	
	/* Its self signed so set the issuer name to be the same as the
 	 * subject.
	 */
	X509_set_issuer_name(x, name);

	if(!X509_sign(x, pk, EVP_md5())) // secured more with sha1? md5/sha1? sha256?
		abort();

	*cert = x;
	*pkey = pk;

	return 1;
}
Example #18
0
static int cl_dev_xmit(struct netdev *nd,struct socket *sk)
{
	int ret;
	struct mbuf mb_d,mb;
	int maxfd,flags=0;
	fd_set in;
	unsigned int nbytes;

	mb_d.mb_data = xmalloc(IP_MAXRECV);
	mb_d.mb_len = 0;
	if(mb_d.mb_data == NULL)
		goto bad;
	
	mb.mb_data = xmalloc(2000*sizeof(char));
	mb.mb_len = 0;
	if(mb.mb_data == NULL)
		goto bad;

	FD_ZERO(&in);
	maxfd = (nd->sk->sk_fd > nd->nd_fd)? nd->sk->sk_fd:nd->nd_fd;
	
	while(1) {
		FD_SET(nd->nd_fd,&in);
		FD_SET(nd->sk->sk_fd,&in);

		ret = select(maxfd+1,&in,NULL,NULL,NULL);
		if(ret == -1 || errno == EINTR)
			continue;
			
		/* we got something from device  */
		if(FD_ISSET(nd->nd_fd,&in)) {
			mb_d.mb_len = recvfrom(nd->nd_fd,mb_d.mb_data,IP_MAXPACKET,0,NULL,NULL);
			if(mb_d.mb_len == -1) {
				perrx("etn_cli_recv:recv");
				goto bad;
			}

#ifdef USE_SSL
			ret = SSL_write(nd->sk->sk_ssl,mb_d.mb_data,mb_d.mb_len);
			if(ret < 0) {
				perrx("etn_cli_recv:send");
				goto bad;
			}
#else
			ret = write(nd->sk->sk_fd,mb_d.mb_data,mb_d.mb_len);
			if(ret == -1) {
				perrx("etn_cli_recv:send");
				goto bad;
			}
#endif
		}
		/* we got something from socket */
		if(FD_ISSET(nd->sk->sk_fd,&in)) {
			/*
			printf("lol\n");
			mb.mb_len = read(nd->sk->sk_fd,mb.mb_data,4096);
			printf("READ : %d\n",mb.mb_len);
			if(mb.mb_len == -1) {
				perrx("recv_sock_handler:recv");
				goto bad;
			}
			*/
			if(read_packet(nd->sk,&mb,1514) <= 0) {
				perrx("read");
				perrx("read_packet():");
				exit(0);
				goto bad;
			}
			
			printf("READ : %d\n",mb.mb_len);
			nbytes = sendto(nd->nd_fd,mb.mb_data,mb.mb_len,0,NULL,0);
			
			if(nbytes == -1) {	
				perrx("recv_sock_handler:sendto");
				goto bad;
			}
			
		}
		
		
	}
	
bad:
	if(mb_d.mb_data)
		free(mb.mb_data);
	exit(0);
	return -1;
}
Example #19
0
int cl_sock_connect(struct socket **sock,char *server,u_short port)
{
	struct socket *sk;
	int fd,ret;
	struct linger so_linger;
	struct hostent *h;
	char **pptr;
	char ip[15]={0};
	struct sockaddr_in cli;

	sk = *sock;
	
	fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd < 0) {
		printf("socket error \n");
		return -1;
	}
#ifdef USE_SSL 
	printf("use ssl\n");
	sk->sk_ctx = cr_ssl_context_cli();
	SSL_CTX_set_options(sk->sk_ctx, SSL_OP_NO_SSLv2);
	sk->sk_ssl = SSL_new(sk->sk_ctx);
#endif

	/* set linger socket option  */
	so_linger.l_onoff = 1;
	so_linger.l_linger = 0;

	/* resolve name */
	h = gethostbyname(server);
	if(!h) {
		perrx("The hostname couln't be resolved\n");
		return -1;
	}
	
	pptr = h->h_addr_list;
	for(;*pptr;pptr++) {
		inet_ntop(h->h_addrtype,*pptr,ip,sizeof(ip));
		break;
	}
	
	memset(&cli,0,sizeof(struct sockaddr_in));
	sk->scli.sin_port = htons(port);
	sk->scli.sin_family = AF_INET;
	sk->scli.sin_addr.s_addr = inet_addr(ip);
	
	/* fill socket buffer  */
	sk->sport = port;
	sk->ipaddr = htonl(sk->sk_cli.sin_addr.s_addr);

	ret = connect(fd,(const struct sockaddr*)&sk->sk_cli,sizeof(struct sockaddr));
	if(ret == -1) {
		perrx("cl_sock_connect() failed");
		return -1;
	}
	sk->sk_fd = fd;

#ifdef USE_SSL
	int r;
	r = cr_ssl_connect(sk);
#endif

	return 0;
}
Example #20
0
int main(int argc,char **argv)
{
	int opt,long_opt_index = 0,ret;
	struct netdev *vdev,dev;
	struct socket sk;
	u_char *ifconf;
	struct linger so_linger;
	u_int mtu=0;

	memset(&dev,0,sizeof(struct netdev));
	memset(&sk,0,sizeof(struct socket));
	ifconf = NULL;
	vdev = &dev;
	vdev->nd_ops = &nd_ops;
	vdev->sk = &sk;

	while( (opt =getopt_long(argc,argv,"hi:I:p:u:vm:H:K:d",long_opt,&long_opt_index)) != -1 ) {
		switch(opt) {
		case 'h':
			banner(argv[0]);
			break;
		case 'i':
			memcpy(&dev.nd_name,optarg,IFNAMSIZ-1);
			break;
		case 'I':
			ifconf = (u_char*)strdup(optarg);
			has_ifconf |=1;
			break;
		case 'p':
			sk.sk_port = atoi(optarg);
			break;
		case 'u':
			dev.nd_owner = (u_int8_t*)strdup(optarg);
			break;
		case 'v':
			verbose |= 1;
			break;
		case 'm':
			mtu = atoi(optarg);
			break;
		case 'K':
			shr_key = (unsigned char*)strdup(optarg);
			break;
		case 'H':
			hwaddr = (u_char *)strdup(optarg);
			break;
		case 'd':
			daemonize |=1;
			break;
		default:
			banner(argv[0]);
			break;
		}
	}
	
	/* device name is not required , 
	   the kernel will give us a random name  */
	dev.nd_flags = IFF_TAP | IFF_NO_PI;
	if(daemonize)
		if(daemon(0,0) == -1) {
			perrx("main():daemon()");
			return -1;
		}

	if(!has_ifconf ) {
		fprintf(stderr,"[!] Device configuration is not set \n");
	} else 
		parse_conf((char*)ifconf,&dev);

	if (!sk.sk_port) 
		sk.sk_port = DEFAULT_PORT;
	
	if(!mtu || mtu < 0 || mtu > 4096)
		vdev->nd_mtu = MTU;
	else
		vdev->nd_mtu = mtu;
	
	if(shr_key == NULL) {
		printf("[-] Shared key is not set\n");
		return -1;
	}
	sk.sk_fd = socket(AF_INET,SOCK_STREAM,0);
	if(sk.sk_fd < 0) {
		perror("main():socket()");
		return -1;
	}

	/* set linger socket option  */
	so_linger.l_onoff = 1;
	so_linger.l_linger = 0;
	
	ret = setsockopt(sk.sk_fd,SOL_SOCKET,SO_LINGER,&so_linger,sizeof(struct linger));
	if(ret == -1) {
		perror("main:setsockopt(SO_LINGER)");
		close(sk.sk_fd);
		return ret;
	}

	/* let's create a virtual device interface */
	if(vdev->nd_ops->init(&dev))
		return -1;
	
	int yes = 1;
	struct socket *sk_cli;
	
	sk.sk_serv.sin_family = AF_INET;
	sk.sk_serv.sin_port = htons(sk.sk_port);
	sk.sk_serv.sin_addr.s_addr = htonl(INADDR_ANY);
	
	/* enable socket address re-use */
	ret = setsockopt(sk.sk_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes));
	if(ret == -1) {
		perror("main:setsockopt(SO_REUSEADDR)");
		close(sk.sk_fd);
		return ret;
	}
	ret = bind(sk.sk_fd,(struct sockaddr*)&sk.sk_serv,sizeof(struct sockaddr_in));
	if(ret == -1) {
		perror("main:bind()");
		close(sk.sk_fd);
		return ret;
	}
	ret = listen(sk.sk_fd,4);
	if(ret == -1) {
		perror("main:listen()");
		return -1;
	}
	if(verbose) 
		printf("[+] Listening on port : %d\n",sk.sk_port);
	
	for(;;) {
		sk_cli =sock_accept(&dev);
		if(!sk_cli)  
			return -1;
		vdev->nd_ops->xmit(vdev,sk_cli);
	}
		
	vdev->nd_ops->exit(vdev);
	return 0;
}
Example #21
0
static int dev_xmit(struct netdev* dev,struct socket *sk)
{
	fd_set in;
	int ret,maxfd;
	struct mbuf mb;
	struct rc4_context ctx;
	
	rc4_prepare_shared_key(&ctx,shr_key);
	memset(&mb,0,sizeof(struct mbuf));
	
	mb.mb_data = (u_int8_t*)malloc(dev->nd_mtu * sizeof(u_int8_t));
	if(!mb.mb_data) {
		perror("dev_xmit:malloc");
		return -1;
	}
	memset(mb.mb_data,0,sizeof(dev->nd_mtu*sizeof(u_int8_t)));
	printf("[+] Connected ... OK\n");
	
	FD_ZERO(&in);
	
	maxfd = (sk->sk_fd > dev->nd_fd)? sk->sk_fd:dev->nd_fd;
	for(;;) {
		FD_SET(dev->nd_fd,&in);
		FD_SET(sk->sk_fd,&in);

		ret = select(maxfd+1,&in,NULL,NULL,NULL);
		if(ret == -1 || errno == EINTR)
			continue;
		
		/* we got something from tun/tap inetface */
		if(FD_ISSET(dev->nd_fd,&in)) {
			mb.mb_len = read(dev->nd_fd,mb.mb_data,dev->nd_mtu);
			if(mb.mb_len == 0) 
				break;
			if(mb.mb_len < 0) {
				if(verbose) 
					perrx("[-] TAP read error");
				goto bad;
			}
			
			rc4_cipher(mb.mb_data,mb.mb_len,&ctx);
			if (verbose)
				printf("[+] Received %d bytes from %s \n",
				       (unsigned int)mb.mb_len,dev->nd_name);
			mb.mb_len = write(sk->sk_fd,mb.mb_data,mb.mb_len);
			if(mb.mb_len <= 0) {
				if(verbose)
					perrx("[-] TAP write error");
				goto bad;
			}	
		}
		
		if(FD_ISSET(sk->sk_fd,&in)) {
			mb.mb_len = read(sk->sk_fd,mb.mb_data,dev->nd_mtu);
			if(mb.mb_len == 0) 
				break;
			if(mb.mb_len < 0) {
				if(verbose) 
					perrx("[-] Socket read error\n");
				goto bad;

			}
				
			if (verbose)
				printf("[+] Received %d bytes from socket\n",(unsigned int)mb.mb_len);
			rc4_cipher(mb.mb_data,mb.mb_len,&ctx);
			mb.mb_len = write(dev->nd_fd,mb.mb_data,mb.mb_len);
			if(mb.mb_len <= 0) {
				if(verbose)
					perrx("[-] Socket write error");
				goto bad;
			}	

		}
		
	}
	return 0;

bad:
	close(sk->sk_fd);
	close(dev->nd_fd);
	if(mb.mb_data)
		free(mb.mb_data);
	return -1;
	
}
Example #22
0
static int dev_init(struct netdev* dev)
{
	struct ifreq ifr;
	struct sockaddr_in *saddr;
	
	memset(&ifr,0,sizeof(struct ifreq));
	
	/* open tap device  */
	dev->nd_fd = open(TUNFILE,O_RDWR);
	if (dev->nd_fd == -1) {
		perror("dev_init():open()");
		return -1;
	}
	if(dev->nd_name)
		memcpy(ifr.ifr_name,dev->nd_name,IFNAMSIZ);
	
	ifr.ifr_flags = dev->nd_flags;
	if(ioctl(dev->nd_fd,TUNSETIFF,(void*)&ifr) < 0) {
		perror("dev_init():ioctl(TUNSETIFF)");
		return -1;
	}

	memcpy(dev->nd_name,ifr.ifr_name,IFNAMSIZ);
	if(verbose)
		printf("[+] Setup a non-persistent tap : %s\n",
		       dev->nd_name);
	
	/* if the device configuration is not set
	   we should wait for dhcp configuration from
	   the internal pwned network 
	 */
	if(has_ifconf) {
		/* set  network ip address  */
		saddr = (struct sockaddr_in*)&ifr.ifr_addr;
		saddr->sin_family = AF_INET;
		saddr->sin_addr.s_addr = dev->nd_ipaddr;
		if(ioctl(dev->sk->sk_fd,SIOCSIFADDR,(void*)&ifr) < 0) {
			perror("dev_init:ioctl(SIOCSIFADDR)");
			return -1;
		}
		
		/* set netmask  */
		saddr = (struct sockaddr_in*)&ifr.ifr_netmask;
		saddr->sin_family = AF_INET;
		saddr->sin_addr.s_addr = htonl(dev->nd_netmask);
		if(ioctl(dev->sk->sk_fd,SIOCSIFNETMASK,(void*)&ifr) < 0) {
			perror("dev_init:ioctl(SIOCSIFNETMASK)");
			return -1;
		}
	}
	
	/* fire up the device  */
	ifr.ifr_flags |= IFF_UP |IFF_RUNNING;
	if(ioctl(dev->sk->sk_fd,SIOCSIFFLAGS,(void*)&ifr) < 0) {
		perror("dev_init:ioctl(SIOCSIFFLAGS)");
		return -1;
	}
	if(hwaddr != NULL) {
		if(sscanf((const char*)hwaddr,"%02x:%02x:%02x:%02x:%02x:%02x",
			  (unsigned int*)&dev->nd_hwaddr[0],
			  (unsigned int*)&dev->nd_hwaddr[1],
			  (unsigned int*)&dev->nd_hwaddr[2],
			  (unsigned int*)&dev->nd_hwaddr[3],
			  (unsigned int*)&dev->nd_hwaddr[4],
			  (unsigned int*)&dev->nd_hwaddr[5]) == 6) {
			
			memset((char*)&ifr.ifr_hwaddr,0,sizeof(struct sockaddr));
			memcpy((char*)&ifr.ifr_hwaddr.sa_data,
			       dev->nd_hwaddr,
			       6);
			ifr.ifr_hwaddr.sa_family = 1; /* Hardware Type (ETHER) */
			if(ioctl(dev->nd_fd,SIOCSIFHWADDR,&ifr) < 0) 
				perrx("dev_init:ioctl(SIOCSIFHWADDR)");
			
		} else 
			printf("dev_init:Invalid Hardware address!\n");
	}	
	/* set MTU */
	ifr.ifr_mtu = dev->nd_mtu;
	if(ioctl(dev->sk->sk_fd,SIOCSIFMTU,(void*)&ifr) < 0) {
		perror("dev_init:ioctl(SIOCSIFFLAGS)");
		return -1;
	}
	
	/* set ownership */
	if(dev->nd_owner) {
		struct passwd *pwd = getpwnam((const char*)dev->nd_owner);
		if(!pwd) {
			perror("dev_init():getpwname()");
			return -1;
		}
		if(ioctl(dev->nd_fd,TUNSETOWNER,pwd->pw_uid) < 0) {
			perror("dev_init():ioctl(SETOWNERSHIP)");
			return -1;
		}
		if(ioctl(dev->nd_fd,TUNSETGROUP,pwd->pw_uid) < 0) {
			perror("dev_init():ioctl(SETOGROUP)");
			return -1;
		}

	}
	return 0;
}
Example #23
0
File: veth.c Project: 0xcc/tapip
static void veth_dev_exit(struct netdev *dev)
{
	if (dev != veth)
		perrx("Net Device Error");
	delete_tap(tap->fd);
}
Example #24
0
int cl_setup_promisc(struct netdev *nd)
{
	char buf[1024]={0};
	struct ifconf ifc;
	struct ifreq *ifr;
	int if_cnt;
	int yes;
	struct sockaddr_ll sll;

	/* set netlink socket */
	nd->nd_fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
	if(nd->nd_fd == -1) {
		perrx("socket:PF_PACKET");
		return -1;
	}
	
	memset(&ifc,0,sizeof(ifc));
	memset(&ifr,0,sizeof(ifr));
	
	ifc.ifc_len = sizeof(buf);
	ifc.ifc_buf = buf;
	
	if(ioctl(nd->nd_fd,SIOCGIFCONF,&ifc) < 0) {
		perrx("ioctl:SIOCGIFCONF");
		return -1;
	}
	/* list all network interfaces 
	   then look for the desired one */
	ifr = ifc.ifc_req;
	if_cnt =ifc.ifc_len / sizeof(struct ifreq);

	ifr = lookup_dev(ifr,&if_cnt,nd);
	if(ifr == NULL) {
		perrx("Couldn't get device name \n");
		return -1;
	}
#ifdef IFCONF
	printfd(2,"interface index : %d\n",ifr->ifr_ifindex);
	printfd(2,"interface address : "IPFMT"\n",
	       ipfmt((int)(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr)));
	printfd(2,"interface netmask : "IPFMT"\n",
		ipfmt((int)(((struct sockaddr_in *)&ifr->ifr_netmask)->sin_addr.s_addr)));
#endif
	/* make sure that the interface is UP & RUNNING */
	ifr->ifr_flags |= IFF_PROMISC;
	ifr->ifr_flags |= IFF_UP |IFF_RUNNING;
	if(ioctl(nd->nd_fd, SIOCSIFFLAGS, ifr) < 0) {
		perrx("ioctl:SIOCGIFCONF");
		return -1;
	}
	
	/* get interface index */
	if (ioctl(nd->nd_fd,SIOCGIFINDEX,ifr)==-1) {
		perrx("SIOCGIFINDEX");
	}
	
	if (setsockopt(nd->nd_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
		perrx("setsockopt:SO_REUSEADDR");
		return -1;
	}
	/* No need for this
	if (setsockopt(nd->nd_fd, SOL_SOCKET, SO_BINDTODEVICE, ifr->ifr_name, IFNAMSIZ-1) == -1)	{
		perrx("SO_BINDTODEVICE");
		return -1;
	}
	*/
	
	memset(&sll,0,sizeof(sll));
	sll.sll_family = AF_PACKET;
	sll.sll_ifindex = ifr->ifr_ifindex;
	sll.sll_protocol = htons(ETH_P_ALL);
	
	if(bind(nd->nd_fd,(struct sockaddr*)&sll,sizeof(sll)) == -1) {
		perrx("bind");
		return -1;
	}
	
	nd->nd_ops->xmit(nd,NULL);
	
	return 0;
}