📄 uml_netjig.c
字号:
init_netdissect(); TAILQ_INIT(&ns.switches); ns.cmdproto_out=stdout; if(isatty(0) || ns.cmdproto) { add_fd(&ns, 0); cmdprompt(&ns); } if(!ns.cmdproto) { /* use standard script! */ netjig1_init(&ns); } publicturn = 1; ns.done = 0; l_fd_array = NULL; l_fd_array_size = 0; l_fds = NULL; l_nfds= 0;// printf("%s attached to unix sockets \n\t'%s,%s'\n and \n\t'%s,%s'\n",// progname, ns.public.ctl_socket_name, ns.public.data_socket_name,// ns.private.ctl_socket_name, ns.private.data_socket_name); onh2toggle=0; onh=NULL; while(!ns.done) { int timeout; char buf[128]; struct nethub *nh; timeout=-1; if(ns.waitplay || !ns.cmdproto || ns.forcetick) { for(nh=ns.switches.tqh_first; nh; nh=nh->nh_link.tqe_next) { /* XXX * actually, this is wrong. The NH's should be arranged * in a priority queue based upon how long till their next * packet should be sent, but for the moment, the rate is * considered constant... tough. */ if(nh->nh_input) { timeout = ns.packetrate; break; /* at least one is enough to invoke timer */ } } } if(ns.debug > 1) { fprintf(stderr, "invoking poll(,%d,) with %s", ns.nfds, timeout ? "waittime" : "no wait"); } /* * we need to allocate a local copy of the arrays to use! * since we are going to modify the arrays based upon I/O */ if(l_nfds != ns.nfds) { l_nfds = ns.nfds; l_fds = realloc(l_fds, l_nfds * sizeof(struct pollfd)); } memcpy(l_fds, ns.fds, l_nfds * sizeof(struct pollfd)); if(l_fd_array_size != ns.fd_array_size) { l_fd_array_size = ns.fd_array_size; l_fd_array = realloc(l_fd_array, l_fd_array_size*sizeof(int)); } memcpy(l_fd_array, ns.fd_array, l_fd_array_size * sizeof(int)); n = poll(l_fds, l_nfds, timeout); if(ns.debug > 1) { fprintf(stderr, " -> %d left %d\n", n, timeout); } if(n < 0 && errno!=EINTR) { perror("poll"); ns.done = 1; } if((timeout!=-1 && n == 0) || ns.forcetick) { int gotinput; int looped; /* timeout */ looped = 0; gotinput=0; while((onh==NULL || onh->nh_input == NULL) && looped < 2) { if(onh==NULL || onh->nh_link.tqe_next==NULL) { /* restart from the beginning, but only once */ onh=ns.switches.tqh_first; onh2=NULL; looped++; } else { /* this implements the tortose and hare loop * detection algorithm, see Allen Van Gelder: * _Efficient Loop Detection in Prolog using * the Tortoise-and-Hare Technique. * JLP 4(1): 23-31 (1987) */ if(onh2toggle) { onh2=onh; } onh2toggle=!onh2toggle; /* advance the pointer once */ onh = onh->nh_link.tqe_next; assert(onh!=onh2); /*oh shit, is there a loop? */ } } /* * now make sure that this source has data. If it doesn't, * then it is because we have wrapped around and found nothing. */ nh=onh; if(nh && nh->nh_input) { struct pcap_pkthdr ph; const u_char *packet; memset(&ph, 0, sizeof(ph)); packet = pcap_next(nh->nh_input, &ph); if(packet == NULL) { nh->nh_input=NULL; } else { gotinput = 1; if(ns.verbose) { fprintf(stderr, "%8s: inserting packet of len %d\n", nh->nh_name, ph.len); } insert_data(&ns, nh, (struct packet *)packet, ph.len); } } if(ns.forcetick == 0) { if(!gotinput && ns.exitonempty) { ns.done=1; } } ns.forcetick = 0; if(!gotinput && ns.waitplay) { finish_waitplay(&ns); } /* timeout the switch tables */ for(nh=ns.switches.tqh_first; nh; nh=nh->nh_link.tqe_next) { hash_periodic(nh); } } if(n>0) { /* first process commands on stdin */ if(l_fd_array_size > 0 && l_fd_array[0]!=-1) { if(l_fds[l_fd_array[0]].revents & POLLIN) { int readlen; readlen = read(0, buf, sizeof(buf)); if(readlen < 0){ perror("Reading from stdin"); break; } else if(readlen == 0){ fprintf(stderr, "EOF on stdin, cleaning up and exiting\n"); break; } else if(ns.cmdproto) { cmdread(&ns, buf, readlen); } /* note that we have processed one descriptor */ l_fds[l_fd_array[0]].revents=0; n--; } else if(l_fds[l_fd_array[0]].revents & POLLHUP) { /* exit! */ ns.done=1; } } /* then process control socket connections */ for(nh=ns.switches.tqh_first; nh; nh=nh->nh_link.tqe_next) { if(nh->ctl_listen_fd < l_fd_array_size && l_fd_array[nh->ctl_listen_fd]!=-1 && l_fds[l_fd_array[nh->ctl_listen_fd]].revents & (POLLIN|POLLHUP)) { accept_connection(&ns, nh); n--; l_fds[l_fd_array[nh->ctl_listen_fd]].revents=0; } } /* then look for packets to process */ for(nh=ns.switches.tqh_first; nh; nh=nh->nh_link.tqe_next) { if(nh->data_fd < l_fd_array_size && l_fd_array[nh->data_fd]!=-1 && l_fds[l_fd_array[nh->data_fd]].revents & POLLIN) { handle_sock_data(&ns, nh); n--; l_fds[l_fd_array[nh->data_fd]].revents=0;#ifdef TUNTAP } else if(nh->tap_fd < l_fd_array_size && l_fd_array[nh->tap_fd]!=-1 && l_fds[l_fd_array[nh->tap_fd]].revents & POLLIN) { handle_tap_data(&ns, nh); n--; l_fds[l_fd_array[nh->data_fd]].revents=0;#endif } } /* finally, check out the sockets that are just listen(2) * for new connections. */ for(nh=ns.switches.tqh_first; nh; nh=nh->nh_link.tqe_next) { handle_port(&ns, nh, l_fds, l_nfds, l_fd_array, l_fd_array_size); } } } signal(SIGINT, SIG_DFL); signal(SIGPIPE, SIG_IGN); for(onh=ns.switches.tqh_first; onh; onh=onh2) { onh2=onh->nh_link.tqe_next; TAILQ_REMOVE(&ns.switches,onh,nh_link); cleanup_nh(onh); } cleanup_njstate(&ns); return 0;}/* * $Log: uml_netjig.c,v $ * Revision 1.27 2003/04/02 20:25:53 mcr * quiet down uml_netjig unless -v or $NETJIGVERBOSE is set. * * Revision 1.26 2003/04/02 02:15:59 mcr * added option to set packet replay rate. * * Revision 1.25 2002/11/11 17:07:59 mcr * add new line for new libnetdissect - but this code * isn't ready yet. * * Revision 1.24 2002/09/05 17:01:42 mcr * make sure that the netdissect system is properly initialized. * * Revision 1.23 2002/09/02 19:33:47 mcr * the WAITPLAY command did work - it signaled end of * packet stream, but then forgot this fact, and didn't * actually exit. * The netjig.tcl will now log to stderr any problems talking * to uml_netjig, so this problem will be more obvious in * the future. * * Revision 1.22 2002/08/30 01:37:35 mcr * double buffered the poll(2) structures so that changes during * use would not affect the system. * changed fd_array to be indirect references so that the poll(2) * loop could more easily double buffer the structures. * * Revision 1.21 2002/08/13 00:50:19 mcr * when using poll(2), the invalid timeout value is -1, * not 0 as with select. * * Revision 1.20 2002/07/21 16:40:34 mcr * clean pid file upon exit, so that directories can be removed * properly. Free up memory that was allocated for the hub. * switch to using mkstemp instead of tmpname for directory * creation - append .d to the generated name. (still not race safe!) * when freeing the hubs, take care not to reference free'ed memory. * * Revision 1.19 2002/07/20 02:12:02 mcr * create a new function, insert_data() that calls send_dst * directly rather than using handle_data() which logs the data. * This avoids having input packets in the packet capture. * * Revision 1.18 2002/07/19 20:49:09 mcr * all incidental messages moved from stdout to stderr since * stdout is often attacked to a pipe in uml_netjig, and writing * to the pipe after it closes causes problems. * cleanup_nh() now properly closes the pcap file before exiting. * host-test.tcl now waits for eof from netjig - this may not work. * netjig does not output anything when told to "QUIT" * * Revision 1.17 2002/07/17 23:52:31 mcr * on some systems, the poll generates an POLLHUP for stdin * which must be dealt with in some way. * * Revision 1.16 2002/07/16 03:48:47 mcr * handle SIGPIPE cleanly. * * Revision 1.15 2002/07/15 09:58:38 mcr * debugging of uml_netjig with new network backend. * * Revision 1.14 2002/07/14 02:48:48 mcr * first version of merged uml_switch/uml_netjig that compiles. * * Revision 1.13 2002/06/17 05:17:01 mcr * when not in cmdproto mode, run the packets as possible. * * Revision 1.12 2002/06/16 23:51:16 mcr * revised uml_netjig - cmd mode has vastly improved, and it * now can run a single UML in cmd mode. * man page still missing. * * Revision 1.11 2002/06/03 01:24:11 mcr * uml_netjig now tries to cleanup (remove) the directories in * /tmp that it made. * * Revision 1.10 2002/05/30 07:06:55 dhr * * spelling * * Revision 1.9 2002/05/08 20:24:28 mcr * this is now uml_netjig version 2. * It has a command protocol (--cmdproto) which permits one to * invoke some functions as desired. * Without this option, it acts like version 1. * * Revision 1.8 2002/01/21 01:08:41 mcr * do not die if -t option is provided, but tcpdump compiled out. * * Revision 1.7 2002/01/12 04:01:36 mcr * another #ifdef NETDISSET for tcpdump_print access. * * Revision 1.6 2002/01/12 03:40:56 mcr * missing #ifdef for on NETDISSECT call. * * Revision 1.5 2002/01/12 02:52:46 mcr * added --debug option to replace #if 0. * * Revision 1.4 2001/10/23 16:34:12 mcr * use "progname" instead of "prog" * fixed public/private confused variables in printf(). * fixed bug in termination logic. * * Revision 1.3 2001/10/14 00:27:10 mcr * added code to play pcap files to both public and private sides. * updated usage. * * Revision 1.2 2001/10/12 20:54:02 mcr * documented environment variables * added arp replies * added --help and fixed Usage(). * * Revision 1.1 2001/10/08 22:54:05 mcr * uml_net program that handles two interfaces. * no support for pcap yet. * * * * Local variables: * c-file-style: "linux" * c-basic-offset: 2 * End: * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -