/******************************************* Active Probing Package: tscdttodt.c - conversion application for the TSC based timestamp file format '*.tscdt' used by the TSC based receiver applications, converts files to the general timestamp file format '*.dt' Created by: Attila Pasztor Version: 0.1 Date: 08.11.2001 Copyright (C) 2001 EMULab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ********************************************/ #include <stdio.h> struct uint128 { unsigned long long n[2]; }; int rs(unsigned long long *a) { int res = a[0] & 1; a[0] = a[0] >> 1; return res; } void rsn(struct uint128 *a, int n) { // max n 63 unsigned long long f = (1<<n) -1; //fprintf(stdout,"rsn n: %d f:%Lx a: %Lx %Lx\n", n,f, a[0].n[1], a[0].n[0]); // low 64 a[0].n[0] = (a[0].n[0] >> n) | ((a[0].n[1] & f) << (64-n)); // high a[0].n[1] = a[0].n[1] >> n; //fprintf(stdout,"rsn n: %d a: %Lx %Lx\n", n, a[0].n[1], a[0].n[0]); } void lsn(struct uint128 *a, int n) { // max n 63 unsigned long long f = ~((1<<(64 - n)) -1); //fprintf(stdout,"lsn n: %d f:%Lx a: %Lx %Lx\n", n,f, a[0].n[1], a[0].n[0]); // high 64 a[0].n[1] = (a[0].n[1] << n) | ((a[0].n[0] & f) >> (64-n)); // low 64 a[0].n[0] = a[0].n[0] << n; //fprintf(stdout,"lsn n: %d a: %Lx %Lx\n", n, a[0].n[1], a[0].n[0]); } struct uint128 plus128(struct uint128 a, struct uint128 b) { struct uint128 c; c.n[0] = a.n[0]; c.n[1] = a.n[1]; c.n[0] += b.n[0]; if (c.n[0] < b.n[0]) { c.n[1]++; } c.n[1] += b.n[1]; return c; } struct uint128 minus128(struct uint128 a, struct uint128 b) { struct uint128 c, tmp2, tmp3; // c = a - b; // a - b = a + (~b + 1) tmp2.n[0] = 1; tmp2.n[1] = 0; tmp3.n[0] = ~b.n[0]; tmp3.n[1] = ~b.n[1]; c = plus128(a, plus128(tmp3, tmp2)); return c; } int greateroreq(struct uint128 a, struct uint128 b) { if ( a.n[1] > b.n[1] ) return 1; if (( a.n[1] == b.n[1] ) && ( a.n[0] >= b.n[0] )) return 1; return 0; } struct uint128 mul64by64(unsigned long long ai, unsigned long long bi) { struct uint128 res,tmp; long long t,a,b; a = ai; b = bi; if ( a > b ) { t = a; a = b; b = t; } res.n[0] = 0; res.n[1] = 0; tmp.n[0] = b; tmp.n[1] = 0; while ( a > 0 ) { if ( rs(&a) ) { // if the lowest bit of a is 1 then add b res = plus128(res,tmp); } // shift tmp lsn(&tmp,1); } return res; } struct uint128 div128by64(struct uint128 a, long long b) { struct uint128 res,tmp; int i = 0; res.n[0] = 0; res.n[1] = 0; tmp.n[0] = b; tmp.n[1] = 0; if ( b != 0 ) { // fprintf(stdout,"div a h:%Lx l:%Lx\n",a.n[1], a.n[0]); while ( greateroreq(a,tmp) ) { lsn(&tmp,1); i++; } rsn(&tmp,1); // fprintf(stdout,"div tmp h:%Lx l:%Lx\n",tmp.n[1], tmp.n[0]); if ( i>0 ) { while (i>0) { lsn(&res,1); if ( greateroreq(a, tmp)) { // a = a - tmp; a = minus128(a, tmp); // fprintf(stdout,"div a h:%Lx l:%Lx\n",a.n[1], a.n[0]); res.n[0] = res.n[0] | 1; } rsn(&tmp,1); i--; } } } return res; } int main(int argc, char *argv[]) { int n,i,fflag, flag, icount, pcount, lastsn; unsigned long long dt; char fname[1000]; unsigned long record[8]; FILE *datafile = NULL; FILE *dt_file = NULL; unsigned long long count = 0; // tsc conversion constant - count unsigned long long time = 0; // tsc conversion constant - time unsigned long long tscts; struct uint128 ts128, first_ts128, ts128sec; int ccflag = 0; unsigned long sec, usec; double dtmp; // Syntax check if ((argc != 2 ) && (argc != 4)) { fprintf(stderr,"Usage: \n"); fprintf(stderr," %s <dtfilename> [<count> <time>] ", argv[0]); fprintf(stderr,"\n"); } else { // Convert input parameters if ( argc == 4 ) { if ( sscanf(argv[2],"%Lu",&count) != 1 ) { fprintf(stderr,"<count> component of the tsc conversion constant should be an integer\n"); exit(0); } if ( sscanf(argv[3],"%Lu",&time) != 1 ) { fprintf(stderr,"<time> component of the tsc conversion constant should be an integer \n"); exit(0); } ccflag = 1; } // read data from file datafile = fopen(argv[1], "r"); if (datafile == NULL) { fprintf(stderr,"Error - couldn't open file:%s\n",argv[1]); return 1; } // open output file strcpy(fname, argv[1]); i = 0; while (fname[i] != '.' && fname[i] != '\0') { i++; } fname[i] = '.'; fname[i+1] = 'd'; fname[i+2] = 't'; fname[i+3] = '\0'; dt_file = fopen(fname, "w"); // save the number of hops as the first value of the output file dt = 1; fwrite(&dt, sizeof(long long), 1, dt_file); fflag = 1; icount = 0; pcount = 0; while (!feof(datafile)) { n = fread(record,8*sizeof(long),1, datafile); if ( n == 1 ) { icount++; if ( fflag == 1) { fprintf(stdout,"Serial number of the first packet found: %u\n", record[0]); } lastsn = record[0]; dt = -1; // test for out of order packets if ( record[0] < pcount ) { fprintf(stderr,"Warning: OUT OF ORDER PACKET or DUPLICATED PACKET DETECTED\n"); fprintf(stderr," packet serial num: %d , this packet is discarded\n",record[0]); } else { // conversion to psim dt output format while (pcount<record[0]) { fwrite(&dt, sizeof(long long), 1, dt_file); pcount++; } // conversion of tsc based time stamp into usec if (ccflag == 0) { time = record[5]; count = record[6]; count = (count << 32) | record[7]; } ts128 = mul64by64(time,1000); tscts = record[3]; tscts = (tscts << 32) | record[4]; ts128 = div128by64(mul64by64(ts128.n[0], tscts), count); if ( ts128.n[1] != 0 ) { fprintf(stderr,"Warning: converted time stamp doesn't fit in 64 bit integer.\n"); } if ( fflag == 1 ) { first_ts128 = ts128; fflag = 0; } ts128 = minus128( ts128, first_ts128); ts128sec = div128by64( ts128, 1000000000); sec = ts128sec.n[0]; ts128sec = minus128( ts128, mul64by64(ts128sec.n[0], 1000000000)); usec = ts128sec.n[0]; // fprintf(stdout,"int: %Lu sec:%u nsec: %u\n",ts128.n[0],sec, usec); dt = sec; dtmp = usec*(1.0e-9); dtmp *= (1 << 16); dtmp *= (1 << 16); usec = dtmp; dt = ( dt << 32 ) | usec; fwrite(&dt, sizeof(long long), 1, dt_file); pcount++; } } } fprintf(stdout,"Serial number of the last packet found : %u\n", lastsn); fprintf(stderr,"%d values were found.\n",icount); fclose(datafile); fclose(dt_file); } }