/* 1100, Fri 17 Apr 98 PKT_TRACE: Collect packet trace Copyright (C) 1997-2002 by Nevil Brownlee, ITSS Technology Development, The University of Auckland */ #include #include #include #include #include #include #include #include #include "..\snmplib\ausnmp.h" #include "..\wattcp\wattcp.h" #include "..\wattcp\pktdrv.h" char tfname[50] = "ptrace.dat"; int target_pps = 500; /* Default reqd packet rate */ int trace_sz = 5001; /* Default trace size */ struct p_t { double s; /* Arrival time, seconds */ Bit16 sz; /* Packet size, bytes */ }; struct p_t *p_table; int n_p = 0; /* Nbr of packets in buffer */ int nxp = 0; /* Index to next packet position */ int time_to_stop = 0; void accept_pkt(unsigned int len, unsigned char far *buff, unsigned int i_face, unsigned int lah_len); void receive(void); double s_uptime(void); /* In trac_upt.cpp */ Bit8 *pkt_rcv_call1(Bit16 len, Bit16 lah_len, Bit8 *buff, Bit16 if_nbr) { if (!time_to_stop) { p_table[nxp].s = s_uptime(); p_table[nxp].sz = len; if (n_p != trace_sz) ++n_p; if (++nxp == trace_sz) nxp = 0; } return (unsigned char far *)NULL; /* Don't bother with call2 */ } void pkt_rcv_call2(Bit16 len, Bit8 *buff, Bit16 if_nbr) { } void pps(void) { double inter, from,to, rate; if (n_p != trace_sz) { from = p_table[0].s; to = p_table[n_p-1].s; } else { from = p_table[nxp].s; to = p_table[nxp == 0 ? trace_sz-1 : nxp-1].s; } inter = to-from; rate = (double)(n_p-1) / inter; printf("%d packets, %.1f s elapsed, %.0f pps\n", n_p-1, inter, rate); if ((int)rate >= target_pps && n_p == trace_sz) time_to_stop = 1; } char *strmov(char *d, char *s) { while (*s != '\0') *d++ = *s++; return d; } int main(int argc, char *argv[]) { int arg, a, c; char cbuf[20], *ap; int n_interfaces; if (argc == 1) { printf("ptrace [-p kilopackets] [-r rate] [-f tracefilename]\n"); printf(" defaults are -p5 -r500 -fptrace.dat\n"); exit(0); } n_interfaces = 0; for (arg = 1; arg < argc; ++arg) { if (argv[arg][0] == '-') { ap = argv[arg]+2; switch (a = argv[arg][1]) { case 'f': /* name of trace file */ if (*ap == '\0') ap = argv[++arg]; ap = strmov(tfname, ap); *ap = '\0'; break; case 'I': /* IP only - no metering */ case 'i': /* Just plain metering */ case 'h': /* Metering with high-performance driver */ if (*ap == NULL) ap = argv[++arg]; if (arg == argc) c = 0; /* No more args */ else c = isdigit(*ap) ? atoi(ap) : 0; /* -h means -h0 */ en_table[n_interfaces].int_nbr = c; if (a != 'I') en_table[n_interfaces].type = a == 'h' ? EN_MT|EN_HP : EN_MT; ++n_interfaces; break; case 'p': /* kilopackets to collect */ if (*ap == '\0') ap = argv[++arg]; trace_sz = atoi(ap)*1000 + 1; break; case 'r': /* target packet rate (pps) */ if (*ap == '\0') ap = argv[++arg]; target_pps = atoi(ap); break; default: printf("Invalid option: -%c\n", argv[arg][1]); exit(0); } } } if (n_interfaces == 0) { en_table[0].type= EN_MT; n_interfaces = 1; } printf("collecting %d packets from %d interfaces\n rate %d pps writing to %s\n", trace_sz-1,n_interfaces, target_pps,tfname); printf(" press ESC to terminate early\n\n"); p_table = (struct p_t *)farmalloc(trace_sz*sizeof(struct p_t)); if (p_table == NULL) { printf("Couldn't allocate packet table\n"); exit(3); } if (pkt_init()) /* Initialise just the packet driver(s) */ exit(1); /* Problems in starting one of the packet driver(s) */ receive(); return 1; /* Keep compiler happy */ } double start_time; int rec_nbr = 0; void write_pkt_info(FILE *f, struct p_t *ptp) { fprintf(f, "%.6f %u\n", ptp->s-start_time, ptp->sz); if (++rec_nbr % 1000 == 0) printf("."); } void write_data(void) { FILE *f; int j; f = fopen(tfname, "w"); if (f == NULL) { printf("couldn't open %s for write\n", tfname); return; } printf("file %s opened for write\n", tfname); if (n_p == trace_sz) { /* Buffer full */ start_time = p_table[nxp].s; /* 'next' position, not written out */ for (j = nxp+1; j != trace_sz; ++j) write_pkt_info(f, &p_table[j]); for (j = 0; j != nxp; ++j) write_pkt_info(f, &p_table[j]); } else { /* Buffer not full */ start_time = p_table[0].s; for (j = 1; j != n_p; ++j) { write_pkt_info(f, &p_table[j]); } } fclose(f); } void receive() { unsigned short k, n; unsigned long tot; int osc = 10; tot = set_timeout(1); for (;;) { if (chk_timeout(tot)) { tot = set_timeout(1); /* 1 second */ if (--osc == 0) { /* Check rate every 10s */ pps(); osc = 10; } if (time_to_stop) { printf("Time to stop !!!\n"); pkt_release(); write_data(); exit(0); } if (kbhit()) { if (getch() == 27) { /* ESC */ pkt_release(); write_data(); printf("\nShutting down\n"); // shut down access to packet driver // exit(0); } } } } } void au_send_mon(int length, unsigned char far *buffer) { return; } /* Default version, never used */