Beispiel #1
0
int main(int argc, char **argv)
{
	int err;
	struct capfs_upcall up;
	struct capfs_downcall down;
	struct capfs_dirent *dent = NULL;
	char *link_name = NULL;
	int opt = 0;
	int capfsd_log_level = CRITICAL_MSG | WARNING_MSG;
	char options[256];
	struct cas_options cas_options = {
doInstrumentation:0,
use_sockets:0,
	};

#ifdef DEBUG
	capfsd_log_level |= INFO_MSG;
	capfsd_log_level |= DEBUG_MSG;
#endif
	set_log_level(capfsd_log_level);
	/* capfsd must register a callback with the meta-data server at the time of mount */
	check_for_registration = 1;
	while((opt = getopt(argc, argv, "dhsn:p:")) != EOF) {
		switch(opt){
			case 's':
				cas_options.use_sockets = 1;
				break;
			case  'd':
				is_daemon = 0;
				break;
			case 'p':
				err = sscanf(optarg, "%x", &capfs_debug);
				if(err != 1){
					usage();
					exiterror("bad arguments");
					exit(1);
				}
				break;
			case 'n':
				num_threads = atoi(optarg);
				break;
			case 'h':
				usage();
				exit(0);
			case '?':
			default:
				usage();
				exiterror("bad arguments");
				exit(1);
		}
	}
		
	if (getuid() != 0 && geteuid() != 0) {
		exiterror("must be run as root");
		exit(1);
	}

	if (setup_capfsdev() < 0) {
		exiterror("setup_capfsdev() failed");
		exit(1);
	}

	if ((dev_fd = open_capfsdev()) < 0) {
		exiterror("open_capfsdev() failed");
		exit(1);
	}
	
	startup(argc, argv);
	/* Initialize the plugin interface */
	capfsd_plugin_init();

	capfs_comm_init();


	/* allocate a 64K, page-aligned buffer for small operations */
	capfs_opt_io_size = ROUND_UP(CAPFS_OPT_IO_SIZE);
	if ((orig_iobuf = (char *) valloc(capfs_opt_io_size)) == NULL) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(orig_iobuf, 0, capfs_opt_io_size);
	capfs_dent_size = ROUND_UP((FETCH_DENTRY_COUNT * sizeof(struct capfs_dirent)));
	/* allocate a suitably large dent buffer for getdents speed up */
	if ((dent = (struct capfs_dirent *) valloc(capfs_dent_size)) == NULL) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(dent, 0, capfs_dent_size);
	/* maximum size of a link target cannot be > 4096 */
	capfs_link_size = ROUND_UP(4096);
	link_name = (char *) valloc(capfs_link_size);
	if(!link_name) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(link_name, 0, capfs_link_size);
	
	fprintf(stderr, "------------ Starting client daemon servicing VFS requests using a thread pool [%d threads] ----------\n",
			num_threads);
	/*
	 * Start up the local RPC service on both TCP/UDP 
	 * for callbacks.
	 */
	pmap_unset(CAPFS_CAPFSD, clientv1);
	if (setup_service(CAPFS_CAPFSD /* program number */,
				clientv1 /* version */,
				-1 /* both tcp/udp */,
				-1 /* any available port */,
				CAPFS_DISPATCH_FN(clientv1) /* dispatch routine */,
				&info) < 0) {
		exiterror("Could not setup local RPC service!\n");
		capfsd_plugin_cleanup();
		exit(1);
	}
	/*
	 * Initialize the hash cache.
	 * Note that we are using default values of cache sizes,
	 * and this should probably be an exposed knob to the user.
	 * CMGR_BSIZE is == CAPFS_MAXHASHLENGTH for SHA1-hash. So we dont need to set
	 * that. We use environment variables to communicate the parameters
	 * to the caches.
	 */
	snprintf(options, 256, "%d", CAPFS_CHUNK_SIZE);
	setenv("CMGR_CHUNK_SIZE", options, 1);
	snprintf(options, 256, "%d", CAPFS_HCACHE_COUNT);
	setenv("CMGR_BCOUNT", options, 1);
	init_hashes();
#if 0
	/*
	 * Initialize the client-side data cache.
	 * Note that we are not using this layer
	 * right now. It is getting fairly complicated already.
	 */
	snprintf(options, 256, "%d", CAPFS_DCACHE_BSIZE);
	setenv("CMGR_BSIZE", options, 1);
	snprintf(options, 256, "%d", CAPFS_DCACHE_COUNT);
	setenv("CMGR_BCOUNT", options, 1);
#endif
	/*
	 * Initialize the client-side data server communication
	 * stuff.
	 */
	clnt_init(&cas_options, num_threads, CAPFS_CHUNK_SIZE);
	
	/* loop forever, doing:
	 * - read from device
	 * - service request
	 * - write back response
	 */
	for (;;) {
		struct timeval begin, end;

		err = read_capfsdev(dev_fd, &up, 30);
		if (err < 0) {
			/* cleanup the hash cache */
			cleanup_hashes();
			/* Cleanup the RPC service */
			cleanup_service(&info);
			capfs_comm_shutdown();
			close_capfsdev(dev_fd);
			/* cleanup the plugins */
			capfsd_plugin_cleanup();
			/* cleanup the client-side stuff */
			clnt_finalize();
			exiterror("read failed\n");
			exit(1);
		}
		if (err == 0) {
			/* timed out */
			capfs_comm_idle();
			continue;
		}
		gettimeofday(&begin, NULL);
		/* the do_capfs_op() call does this already; can probably remove */
		init_downcall(&down, &up);

		err = 0;
		switch (up.type) {
			/* all the easy operations */
		case GETMETA_OP:
		case SETMETA_OP:
		case LOOKUP_OP:
		case CREATE_OP:
		case REMOVE_OP:
		case RENAME_OP:
		case SYMLINK_OP:
		case MKDIR_OP:
		case RMDIR_OP:
		case STATFS_OP:
		case HINT_OP:
		case FSYNC_OP:
		case LINK_OP:
		{
			PDEBUG(D_UPCALL, "read upcall; type = %d, name = %s\n", up.type,
					 up.v1.fhname);
			err = do_capfs_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for type %d\n", up.type);
			}
			break;
			/* the more interesting ones */
		}
		case GETDENTS_OP:
			/* need to pass location and size of buffer to do_capfs_op() */
			up.xfer.ptr = dent;
			up.xfer.size = capfs_dent_size;
			err = do_capfs_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for getdents\n");
			}
			break;
		case READLINK_OP:
			/* need to pass location and size of buffer to hold the target name */
			up.xfer.ptr = link_name;
			up.xfer.size = capfs_link_size;
			err = do_capfs_op(&up, &down);
			if(err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for readlink\n");
			}
			break;
		case READ_OP:
			err = read_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "read_op failed\n");
			}
			break;
		case WRITE_OP:
			err = write_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed\n");
			}
			break;
			/* things that aren't done yet */
		default:
			err = -ENOSYS;
			break;
		}
		gettimeofday(&end, NULL);
		/* calculate the total time spent servicing this call */
		if (end.tv_usec < begin.tv_usec) {
			end.tv_usec += 1000000;
			end.tv_sec--;
		}
		end.tv_sec -= begin.tv_sec;
		end.tv_usec -= begin.tv_usec;
		down.total_time = (end.tv_sec * 1000000 + end.tv_usec);
		down.error = err;

		switch(up.type)
		{
		case HINT_OP:
			/* this is a one shot hint, we don't want a response in case of HINT_OPEN/HINT_CLOSE */
			if (up.u.hint.hint == HINT_CLOSE || up.u.hint.hint == HINT_OPEN) {
				err = 0;
				break;
			}
			/* fall through */
		default:
			/* the default behavior is to write a response to the device */
			err = write_capfsdev(dev_fd, &down, -1);
			if (err < 0) {
				/* cleanup the hash cache */
				cleanup_hashes();
				/* Cleanup the RPC service */
				cleanup_service(&info);
				capfs_comm_shutdown();
				close_capfsdev(dev_fd);
				/* Cleanup the plugins */
				capfsd_plugin_cleanup();
				/* cleanup the client-side stuff */
				clnt_finalize();
				exiterror("write failed");
				exit(1);
			}
			break;
		}

		/* If we used a big I/O buffer, free it after we have successfully
		 * returned the downcall.
		 */
		if (big_iobuf != NULL) {
			free(big_iobuf);
			big_iobuf = NULL;
		}
	}
	/* Not reached */
	/* cleanup the hash cache */
	cleanup_hashes();
	/* Cleanup the RPC service */
	cleanup_service(&info);
	capfs_comm_shutdown();
	close_capfsdev(dev_fd);
	/* cleanup the plugins */
	capfsd_plugin_cleanup();
	/* cleanup the client-side stuff */
	clnt_finalize();
	exit(1);
}
Beispiel #2
0
int main(int argc, char **argv) {
	pcap_t *pcap;
	char errbuf[PCAP_ERRBUF_SIZE];
	const u_char *pkt;
	struct pcap_pkthdr hdr;
	struct ether_header *eptr;
	struct ip *ip_hdr;   
	struct tcphdr *tcp_hdr;   
	unsigned long nbp,nbip,nbtcp;
	unsigned long long totalSize;
	flow * flowrec;
	int c,optpkt;
	struct timeval t0,t1;
	uint32_t last_expiration,current_ts;

	// Default Paramaters for the classification
	labeling=clusterport;
	SSL_labeling=SSL_clusterport;
	sslparsing=0;
	threshold=-255;
	action=ACTION_LABEL;
	memory=NOOPTMEM;
	pktlimit=model.nbpackets;
	optpkt=pktlimit;

	stats.nbstats=0;
	bzero(stats.timeidx,sizeof(stats.timeidx));
	bzero(stats.creations,sizeof(stats.creations));
	bzero(stats.deletions,sizeof(stats.deletions));

	nbflows=0;
	last_expiration=0;

	// Parsing options
	while ((c = getopt (argc, argv, "m:hCDPLSt:p:")) != -1)
		switch (c) {
			case 'h':
				usage(argv);
				break;
			case 'P':
				action=ACTION_PARSE;
				break;
			case 'L':
				action=ACTION_LABEL;
				break;
			case 'D':
				labeling=dominant;
				SSL_labeling=dominant;
				break;
			case 'C':
				labeling=clusterport;
				SSL_labeling=SSL_clusterport;
				break;
			case 'm':
				if (atoi(optarg)>=0) {
					memory=atoi(optarg);
					break;
				} else {
					fprintf(stderr,"Invalid Memory option\n");
					usage(argv);
				}
				break;
			case 'S':
				sslparsing=1;
				break;
			case 't':
				if (atoi(optarg)>0) {
					threshold=-atoi(optarg);
					break;
				} else {
					fprintf(stderr,"Invalid threshold value\n");
					usage(argv);
				}
			case 'p':
				if (atoi(optarg)>0) {
					optpkt=atoi(optarg);
					break;
				} else {
					fprintf(stderr,"Invalid packet value\n");
					usage(argv);
				}

			case '?':
				if (isprint (optopt))
					fprintf (stderr, "Unknown option `-%c'.\n", optopt);
				else
					fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
				usage(argv);
			default:
				usage(argv);
		}


	if (action==ACTION_PARSE) pktlimit=optpkt;

	if (optind>=argc) {
		fprintf(stderr,"No file specified\n");
		usage(argv);
	}
	
	// Opening pcap file
	fprintf(stderr,"Opening file : %s\n",argv[optind]);
	if ((pcap = pcap_open_offline(argv[optind], errbuf)) == NULL) {
		fprintf(stderr,"Error opening pcap file : %s\n",errbuf);
		usage(argv);
	}

	init_hashes ();

	// Empty connection to start list
	first_flow=(flow*)malloc(sizeof(flow));
	first_flow->src.s_addr=0;
	first_flow->dst.s_addr=0;
	first_flow->sport=0;
	first_flow->dport=0;

	active_flows=first_flow;


	// Parse packets one by one
	nbp=0;nbip=0;nbtcp=0;
	totalSize=0;
	gettimeofday (&t0,NULL);
	while (pkt  = pcap_next( pcap,  &hdr )) {
		nbp++;
		totalSize+=hdr.len;

		current_ts=hdr.ts.tv_sec;
		if (last_expiration==0) last_expiration=current_ts;
		if (current_ts-last_expiration>CLEAN_TIME) {
			if (memory>=OPT_GARBAGE) clean_flows(first_flow->next,current_ts);
			statistics(current_ts-last_expiration);
			last_expiration=current_ts;
		}

		if (nbp % PRINTPKT== 0) {
			fprintf(stderr, "Pkt : %lu",nbp);
	    		fprintf(stderr, "\r");
			fflush(stderr);
		}

		eptr = (struct ether_header *) pkt;
		if (ntohs (eptr->ether_type) != ETHERTYPE_IP) {
			continue;
		} else {
			nbip++;
			ip_hdr=(struct ip *)(pkt+14);

			if (ip_hdr->ip_p==IPPROTO_TCP && ((ntohs (ip_hdr->ip_off) & IP_OFFMASK)==0)) {
				nbtcp++;
				count_flow(ip_hdr,hdr.caplen-14,hdr.ts.tv_sec);
			}
		}
	}

	if (memory>=OPT_GARBAGE) clean_flows(first_flow->next,current_ts);
	statistics(current_ts-last_expiration);
	last_expiration=current_ts;
	dump_flows(first_flow->next);
	statistics(1);

	gettimeofday (&t1,NULL);
	pcap_close(pcap);

	fprintf(stderr,"\n%lu Packets parsed in %.2fms\n(%lu non-ip / %lu non-tcp)\n"
			"TCP Connections with Syn: %lu\n"
			"Total Volume: %llu\n"
			"Duration: %lu\n",
			nbp,
			(float)((t1.tv_sec-t0.tv_sec)*1000000 + (t1.tv_usec-t0.tv_usec))/1000,
			nbp-nbip,nbp-nbtcp,flow_hash->total_insert,totalSize,stats.timeidx[stats.nbstats]);
	
	//dump_hashtab_stats(flow_hash);
	//print_statistics();
}