/* * NEWSWITCH --arpreply switch-name */ int create_new_switch(struct netjig_state *ns, int argc, char **argv) { int opt; struct nethub *nh; int arpreply; static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"arpreply", no_argument, 0, 'a'}, {NULL, 0, 0, 0}, }; arpreply=0; opterr=0; optind=1; while((opt = getopt_long(argc, argv, "ha", long_options, NULL)) != EOF) { switch(opt) { default: case 'h': fprintf(ns->cmdproto_out,"FAIL 3 LINES\n"); goto usage; case 'a': arpreply++; break; } } if(optind+1 != argc) { fprintf(ns->cmdproto_out,"FAIL 4 LINES\n"); usage: fprintf(ns->cmdproto_out,"ERROR - missing switchname\n"); fprintf(ns->cmdproto_out,"NEWSWITCH --arpreply switchname\n" "\tswitchname is name of hub\n" "\treturns environment variables for new sockets\n"); fflush(stdout); return 1; } nh = init_nethub(ns, argv[optind], NULL, NULL, /* compat_v0 */ 1); nh->nh_allarp = arpreply; fprintf(ns->cmdproto_out,"OK 3 LINES\n"); fprintf(ns->cmdproto_out,"ARPREPLY=%d\n", arpreply); fprintf(ns->cmdproto_out,"%s\n%s\n", nh->ctl_socket_name_env, nh->data_socket_name_env); fflush(ns->cmdproto_out); return 0; }
int main(int argc, char **argv) { int hub, compat_v0; int n, i; char *tap_dev = NULL; char *home; char *switchname; int *l_fd_array; int l_fd_array_size; /* so we can grow it in add_fd() */ struct pollfd *l_fds; /* array of input sources */ int l_nfds; /* number of relevant entries */ hub = 0; compat_v0=0; switchname="switch"; global_ns = malloc(sizeof(*global_ns)); memset(global_ns, 0, sizeof(*global_ns)); TAILQ_INIT(&global_ns->switches); progname = argv[0]; argv++; argc--; while(argc > 0){ if(!strcmp(argv[0], "-unix")){ if(argc < 2) Usage(); ctl_socket = argv[1]; argc -= 2; argv += 2; if(!compat_v0) break; if(argc < 1) Usage(); data_socket = argv[0]; argc--; argv++; } else if(!strcmp(argv[0], "-name")){ if(argc < 2) Usage(); switchname = argv[1]; ctl_socket=NULL; data_socket=NULL; argc -= 2; argv += 2; } else if(!strcmp(argv[0], "-tap")){ #ifdef TUNTAP tap_dev = argv[1]; argv += 2; argc -= 2; #else fprintf(stderr, "-tap isn't supported since TUNTAP isn't enabled\n"); Usage(); #endif } else if(!strcmp(argv[0], "-hub")){ printf("%s will be a hub instead of a switch\n", progname); hub = 1; argc--; argv++; } else if(!strcmp(argv[0], "-compat-v0")){ printf("Control protocol 0 compatibility\n"); compat_v0 = 1; data_socket = "/tmp/uml.data"; argc--; argv++; } else Usage(); } /* set socket base dir to $HOME/.uml, defaulting back to /tmp/uml, * if $HOME is not set. */ if((home=getenv("HOME"))==NULL) { global_ns->socketbasedir="/tmp/uml"; } else { global_ns->socketbasedir=xmalloc(strlen(home)+1+sizeof(".umlnet")+1); sprintf(global_ns->socketbasedir, "%s/.umlnet", home); } global_nh = init_nethub(global_ns, switchname, ctl_socket, data_socket, compat_v0); global_nh->nh_hub = hub; if(signal(SIGINT, sig_handler) < 0) perror("Setting handler for SIGINT"); hash_timer_init(); if(compat_v0) printf("%s attached to unix sockets '%s' and '%s'\n", progname, global_nh->ctl_socket_name, (global_nh->data_socket_name ? global_nh->data_socket_name : "-abstract-named-")); else printf("%s attached to unix socket '%s'\n", progname, global_nh->ctl_socket_name); if(isatty(0)) add_fd(global_ns, 0); #ifdef TUNTAP if(tap_dev != NULL) { global_nh->tap_fd = open_tap(global_ns, global_nh, tap_dev); } #endif l_fd_array = NULL; l_fd_array_size = 0; l_fds = NULL; l_nfds= 0; while(1){ char buf[128]; /* * 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 != global_ns->nfds) { l_nfds = global_ns->nfds; l_fds = realloc(l_fds, l_nfds * sizeof(struct pollfd)); } memcpy(l_fds, global_ns->fds, l_nfds * sizeof(struct pollfd)); if(l_fd_array_size != global_ns->fd_array_size) { l_fd_array_size = global_ns->fd_array_size; l_fd_array = realloc(l_fd_array, l_fd_array_size*sizeof(int)); } memcpy(l_fd_array, global_ns->fd_array, l_fd_array_size * sizeof(int)); n = poll(l_fds, l_nfds, -1); if(n < 0){ if(errno == EINTR) continue; perror("poll"); break; } for(i = 0; i < l_nfds; i++){ if(l_fds[i].revents == 0) continue; if(l_fds[i].fd == 0){ if(l_fds[i].revents & POLLHUP){ printf("EOF on stdin, cleaning up and exiting\n"); goto out; } n = read(0, buf, sizeof(buf)); if(n < 0){ perror("Reading from stdin"); break; } else if(n == 0){ printf("EOF on stdin, cleaning up and exiting\n"); goto out; } } else if(l_fds[i].fd == global_nh->ctl_listen_fd){ if(l_fds[i].revents & POLLHUP){ printf("Error on connection fd\n"); continue; } accept_connection(global_ns, global_nh); } else if(l_fds[i].fd == global_nh->data_fd) { handle_sock_data(global_ns, global_nh); } #ifdef TUNTAP else if(l_fds[i].fd == global_nh->tap_fd) { handle_tap_data(global_ns, global_nh); } #endif else { handle_port(global_ns, global_nh, l_fds, l_nfds, l_fd_array, l_fd_array_size); } } } out: cleanup(); return 0; }