Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
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;
}