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); }
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(); }