⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uml_netjig.c

📁 FREESWAN VPN源代码包
💻 C
📖 第 1 页 / 共 2 页
字号:
      "\t--exitonempty (-e)          exit when no more packets to read\n"      "\t--playpublic (-p) <file>    pcap(3) file to feed into public side\n"      "\t--recordpublic (-r) <file>  pcap(3) file to write from public side\n"      "\t--playprivate (-P) <file>   pcap(3) file to feed into private side\n"      "\t--recordprivate (-R) <file> pcap(3) file to write from private side\n"      "\t--unix (-u) <dir>           directory to put sockets (default $TMPDIR)\n"      "\t--startup (-s) <script>     script to run after sockets are setup.\n"#ifdef NETDISSECT	  "\t--tcpdump (-t)           dump packets with tcpdump-dissector\n"#else	  "\t--tcpdump (-t)           (not available - dissector not built in)\n"#endif#ifdef ARP_PROCESS	  "\t--arpreply (-a)          respond to ARP requests\n"#else	  "\t--arpreply (-a)          (not available - arp replies disabled)\n"#endif	  "\t--help                   this message\n\n");  exit(1);}#ifdef NETDISSECT/* Like default_print() but data need not be aligned */voiddefault_print_unaligned(struct netdissect_options *ipdo,			register const u_char *cp, register u_int length){	register u_int i, s;	register int nshorts;	if (ipdo->ndo_Xflag) {		ascii_print(ipdo, cp, length);		return;	}	nshorts = (u_int) length / sizeof(u_short);	i = 0;	while (--nshorts >= 0) {		if ((i++ % 8) == 0)			(void)printf("\n\t\t\t");		s = *cp++;		(void)printf(" %02x%02x", s, *cp++);	}	if (length & 1) {		if ((i % 8) == 0)			(void)printf("\n\t\t\t");		(void)printf(" %02x", *cp);	}}/* * By default, print the packet out in hex. */voiddefault_print(struct netdissect_options *ndo,	      register const u_char *bp, register u_int length){	default_print_unaligned(ndo, bp, length);}#endifvoid init_nethub(struct nethub *nh, char *base, char *type){	int one;	char *env;	one = 1;	memset(nh, 0, sizeof(*nh));	TAILQ_INIT(&nh->connections);	nh->nh_name = strdup(type);	/* setup ARP stuff */	nh->nh_allarp = 0;		nh->nh_defaultgate.s_addr = 0;		nh->nh_defaultether[0]=0x10;	nh->nh_defaultether[1]=0x00;	nh->nh_defaultether[2]=0x00;	nh->nh_defaultether[3]=type[0];	nh->nh_defaultether[4]=type[1];	nh->nh_defaultether[5]=type[2];	/* cons up the names, and stick them in the environment */	env = xmalloc(sizeof("UML_")+strlen(type)+sizeof("CTL=")+		      strlen(base)+sizeof("/ctl")+1);	sprintf(env, "UML_%s_CTL=%s/ctl", type, base);	nh->ctl_socket_name = strchr(env, '=')+1;	putenv(env);	env = xmalloc(sizeof("UML_")+strlen(type)+sizeof("DATA=")+		      strlen(base)+sizeof("/data")+1);	sprintf(env, "UML_%s_DATA=%s/data", type, base);	nh->data_socket_name = strchr(env, '=')+1;	putenv(env);	if((nh->ctl_listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){		perror("socket");		exit(1);	}	if(setsockopt(nh->ctl_listen_fd,		      SOL_SOCKET, SO_REUSEADDR, (char *) &one, 		      sizeof(one)) < 0){		perror("setsockopt");		exit(1);	}	if(fcntl(nh->ctl_listen_fd, F_SETFL, O_NONBLOCK) < 0){		perror("Setting O_NONBLOCK on connection fd");		exit(1);	}		if((nh->data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0){		perror("socket");		exit(1);	}	if(fcntl(nh->data_fd, F_SETFL, O_NONBLOCK) < 0){		perror("Setting O_NONBLOCK on data fd");		exit(1);	}	bind_sockets(nh);	if(listen(nh->ctl_listen_fd, 15) < 0){		perror("listen");		exit(1);	}	}static int debug=0;int main(int argc, char **argv){  int n, done;  int  exitonempty;  char *publicbase, *privatebase;  char *basedir, *startup;  char *playprivatefile, *recordprivatefile;  char *playpublicfile, *recordpublicfile;  int   publicturn;  char errbuf[256];  int opt;  int arpreply;  static struct option long_options[] =  {    {"help",        no_argument, 0, 'h'},    {"arpreply",    no_argument, 0, 'a'},    {"debug",       no_argument, 0, 'd'},    {"exitonempty", no_argument, 0, 'e'},    {"tcpdump",     no_argument, 0, 't'},    {"playpublic", required_argument, 0, 'p'},    {"playprivate",required_argument, 0, 'P'},    {"recordpublic",  required_argument, 0, 'r'},    {"recordprivate", required_argument, 0, 'R'},    {"unix",    required_argument, 0, 'u'},    {"startup", required_argument, 0, 's'},  };    basedir    = NULL;  publicbase = NULL;  privatebase= NULL;  startup    = NULL;  arpreply   = 0;  exitonempty= 0;  playpublicfile  = playprivatefile   = NULL;  recordpublicfile= recordprivatefile = NULL;  progname = argv[0];  if(strrchr(progname, '/')) {	  progname=strrchr(progname, '/')+1;  }  while((opt = getopt_long(argc, argv, "adehp:P:r:R:s:tu:",			   long_options, NULL)) !=  EOF) {    switch(opt) {    case 'a':	    arpreply++;	    break;    case 'd':	    debug++;	    break;    case 'e':	    exitonempty++;	    break;    case 'u':	    basedir = optarg;	    break;    case 's':	    startup = optarg;	    break;	        case 't':	    fprintf(stderr, "tcpdump dissector not available\n");#ifdef NETDISSECT	    tcpdump_print = 1;#endif	    break;    case 'p':      playpublicfile = optarg;      break;    case 'P':      playprivatefile = optarg;      break;    case 'r':      recordpublicfile= optarg;      break;    case 'R':      recordprivatefile= optarg;      break;    case 'h':    default:      Usage();    }  }  if(basedir == NULL) {    n=1000;    while(n>0) {      basedir=tempnam(NULL, "uml");      if(mkdir(basedir, 0700) == 0) {	break;      }      n--;    }    if(n==0) {      fprintf(stderr, "failed to make tmpdir (last=%s)\n",	      basedir);      exit(1);    }  }    if(!publicbase) {    publicbase=xmalloc(strlen(basedir)+sizeof("/public")+1);    sprintf(publicbase, "%s/public", basedir);    if(mkdir(publicbase, 0700) != 0 && errno!=EEXIST) {      perror(publicbase);      exit(1);    }  }    if(!privatebase) {    privatebase=xmalloc(strlen(basedir)+sizeof("/private")+1);    sprintf(privatebase, "%s/private", basedir);    if(mkdir(privatebase, 0700) != 0 && errno!=EEXIST) {      perror(privatebase);      exit(1);    }  }  #ifdef NETDISSECT	    memset(&gndo, 0, sizeof(gndo));  gndo.ndo_default_print = default_print;  /* dump ethernet headers */  gndo.ndo_eflag = 1;  /* avoid DNS lookups */  gndo.ndo_nflag = 0;#endif  init_nethub(&public, publicbase, "public");  init_nethub(&private,privatebase,"private");  public.nh_allarp = arpreply;  private.nh_allarp= arpreply;  if(recordpublicfile) {	  pcap_t *pt;	  printf("%s: will record to %s from public interface\n",		 progname, recordpublicfile);	  public.nh_outputFile = recordpublicfile;	  pt = pcap_open_dead(DLT_EN10MB, 1536);	  public.nh_output = pcap_dump_open(pt, recordpublicfile);	  if(public.nh_output == NULL) {	    fprintf(stderr, "pcap_dump_open failed to open %s\n",		    recordpublicfile);	    exit(1);	  }  }  if(recordprivatefile) {	  pcap_t *pt;	  printf("%s: will record to %s from private interface\n",		 progname, recordprivatefile);	  private.nh_outputFile = recordprivatefile;	  pt = pcap_open_dead(DLT_EN10MB, 1536);	  private.nh_output = pcap_dump_open(pt, recordprivatefile);	  if(private.nh_output == NULL) {	    fprintf(stderr, "pcap_dump_open failed to open %s\n",		    recordprivatefile);	    exit(1);	  }  }  if(playpublicfile) {	  printf("%s: will play %s to public interface\n",		 progname, playpublicfile);	  public.nh_inputFile = playpublicfile;	  public.nh_input = pcap_open_offline(playpublicfile, errbuf);	  if(public.nh_input == NULL) {		  fprintf(stderr, "pcap_open_offline: %s\n", errbuf);		  exit(1);	  }  }	    if(playprivatefile) {	  printf("%s: will play %s to private interface\n",		 progname, playprivatefile);	  private.nh_inputFile = playprivatefile;	  private.nh_input = pcap_open_offline(playprivatefile, errbuf);	  if(private.nh_input == NULL) {		  fprintf(stderr, "pcap_open_offline: %s\n", errbuf);		  exit(1);	  }  }	    printf("%s: will exit on empty: %s\n", progname,	 exitonempty ? "yes" : "no ");  if(signal(SIGINT, sig_handler) < 0)    perror("Setting handler for SIGINT");  if(startup) {	  system(startup);  }  printf("%s attached to unix sockets \n\t'%s,%s'\n and \n\t'%s,%s'\n",	 progname, public.ctl_socket_name, public.data_socket_name,	 private.ctl_socket_name, private.data_socket_name);  FD_ZERO(&perm_fds);  if(isatty(0)) FD_SET(0, &perm_fds);  FD_SET(public.ctl_listen_fd, &perm_fds);  FD_SET(private.ctl_listen_fd, &perm_fds);  FD_SET(public.data_fd, &perm_fds);  FD_SET(private.data_fd, &perm_fds);  max_fd = -1;  max_fd = MAX(max_fd,  public.ctl_listen_fd);  max_fd = MAX(max_fd, private.ctl_listen_fd);  max_fd = MAX(max_fd,  public.data_fd);  max_fd = MAX(max_fd, private.data_fd);  publicturn = 1;  done = 0;  while(!done)  {    fd_set temp;    struct timeval tv, *waittime;    char buf[128];    waittime=NULL;    if(public.nh_input ||       private.nh_input) {      tv.tv_sec  = 0;      tv.tv_usec = 500000;      waittime = &tv;    }    temp = perm_fds;    if(debug > 1) {	    printf("invoking select with %s %s %s",		   waittime ? "waittime" : "no wait",		   public.nh_input ?  "public"  : "no-public",		   private.nh_input ? "private" : "no-priv");	    fflush(stdout);    }    n = select(max_fd + 1, &temp, NULL, NULL, waittime);        if(debug > 1) {	    printf(" -> %d left %lu\n", n, tv.tv_usec);    }    if(n < 0){      perror("select");      done = 1;    }    if(waittime && tv.tv_usec == 0) {      struct nethub *nh;      /* timeout */      if(publicturn) {	nh = &public;      } else {	nh = &private;      }      if(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 {	  printf("%8s: inserting packet of len %d\n", nh->nh_name, ph.len);	  forward_data(nh, (struct packet *)packet, ph.len);	}      }      publicturn = !publicturn;            if(public.nh_input  == NULL &&	 private.nh_input == NULL &&	 exitonempty) {	done=1;      }    }    if(n > 0) {      if(FD_ISSET(0, &temp)){	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");	  break;	}	continue;      }      else if(FD_ISSET(public.ctl_listen_fd, &temp)){	accept_connection(&public);	FD_CLR(public.ctl_listen_fd, &temp);      }      else if(FD_ISSET(private.ctl_listen_fd, &temp)){	accept_connection(&private);	FD_CLR(private.ctl_listen_fd, &temp);      }            if(FD_ISSET(public.data_fd, &temp)){	handle_data(&public);	FD_CLR(public.data_fd, &temp);      } else if(FD_ISSET(private.data_fd, &temp)){	handle_data(&private);	FD_CLR(private.data_fd, &temp);      }      handle_connections(&public, &temp, max_fd + 1);      handle_connections(&private,&temp, max_fd + 1);    }  }  cleanup(&public);  cleanup(&private);  return 0;}/* * $Log: uml_netjig.c,v $ * Revision 1.2  2002/11/05 01:51:44  ken * /testing tree from 1.99 * * 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 + -