/* 1315, Wed 10 Sep 97 NMC_C64.C: Counter64 format routines. Could become a 64-bit class one day ... Copyright (C) 1997-2002 by Nevil Brownlee, CAIDA | University of Auckland */ /* * $Log: nmc_c64.c,v $ * Revision 1.1.1.2.2.7 2002/02/23 01:57:21 nevil * Moving srl examples to examples/ directory. Modified examples/Makefile.in * * Revision 1.1.1.2.2.3 2000/06/06 03:38:12 nevil * Combine NEW_ATR with TCP_ATR, various bug fixes * * Revision 1.1.1.2 1999/10/03 21:06:17 nevil * *** empty log message *** * * Revision 1.1.1.1.2.1 1999/01/08 01:38:31 nevil * Distribution file for 4.3b7 * * Revision 1.1.1.1 1998/11/16 03:57:27 nevil * Import of NeTraMet 4.3b3 * * Revision 1.1.1.1 1998/11/16 03:22:00 nevil * Import of release 4.3b3 * * Revision 1.1.1.1 1998/10/28 20:31:25 nevil * Import of NeTraMet 4.3b1 * * Revision 1.1.3.2 1998/10/18 23:44:10 nevil * Added Nicolai's patches, some 'tidying up' of the source * * Revision 1.1.3.1 1998/10/13 02:48:23 nevil * Import of Nicolai's 4.2.2 * * Revision 1.1.1.1 1998/08/24 12:09:28 nguba * NetraMet 4.2 Original Distribution * * Revision 1.3 1998/05/07 04:28:53 rtfm * Implement NetFlowMet, the Cisco NetFlow RTFM meter */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include "ausnmp.h" #include "asn1.h" #include "nmc.h" #include "nmc_c64.h" #if SIZEOF_LONG_LONG == 8 || SIZEOF_LONG == 8 char *putc64(char *bp, counter64 *c) { sprintf(bp, "%lu", *c); return bp + strlen(bp); } char *getc64(counter64 *c, char *bp) { *c = 0; while (isdigit(*bp)) { *c *= 10; *c += *bp-'0'; ++bp; } return bp; } #elif SIZEOF_LONG == 4 /* counter64 formatting routines for machines which use 32-bit integers */ union u64 { counter64 c; /* high low */ unsigned short u[4]; /* [0] [1] [2] [3] */ }; /* [1] [0] [3] [2] on little-endian machines */ void c64timesu16(union u64 *p, union u64 *j, unsigned short k) { /* p = j * k */ unsigned long x; #if WORDS_BIGENDIAN x = j->u[3] * k; p->u[3] = x & 0xFFFF; x = j->u[2] * k + (x >> 16); p->u[2] = x & 0xFFFF; x = j->u[1] * k + (x >> 16); p->u[1] = x & 0xFFFF; x = j->u[0] * k + (x >> 16); p->u[0] = x & 0xFFFF; #else x = j->u[2] * k; p->u[2] = x & 0xFFFF; x = j->u[3] * k + (x >> 16); p->u[3] = x & 0xFFFF; x = j->u[0] * k + (x >> 16); p->u[0] = x & 0xFFFF; x = j->u[1] * k + (x >> 16); p->u[1] = x & 0xFFFF; #endif } unsigned int c64divu16(union u64 *q, union u64 *j, unsigned short k) { /* q = j / k, result = j % k */ unsigned long x; #if WORDS_BIGENDIAN q->u[0] = j->u[0] / k; x = ((j->u[0] % k) << 16) + j->u[1]; q->u[1] = x / k; x = ((x % k) << 16) + j->u[2]; q->u[2] = x / k; x = ((x % k) << 16) + j->u[3]; q->u[3] = x / k; #else q->u[1] = j->u[1] / k; x = ((j->u[1] % k) << 16) + j->u[0]; q->u[0] = x / k; x = ((x % k) << 16) + j->u[3]; q->u[3] = x / k; x = ((x % k) << 16) + j->u[2]; q->u[2] = x / k; #endif return x % k; } char *putc64(char *bp, counter64 *c) { char nb[30]; int x; counter64 cc, d; nb[x = sizeof(nb)-1] = '\0'; memcpy(&cc, c, sizeof(counter64)); do { nb[--x] = c64divu16((union u64 *)&d, (union u64 *)&cc, 10) + '0'; memcpy(&cc, &d, sizeof(counter64)); } while (cc.low != 0 || cc.high != 0); while (nb[x] != '\0') *bp++ = nb[x++]; *bp = '\0'; return bp; } char *getc64(counter64 *c, char *bp) { counter64 cc, m; cc.high = cc.low = 0; while (isdigit(*bp)) { c64timesu16((union u64 *)&m, (union u64 *)&cc, 10); memcpy(&cc, &m, sizeof(counter64)); add_Bit32_to_counter64(cc, *bp-'0'); ++bp; } memcpy(c, &cc, sizeof(counter64)); return bp; } #else #error sizeof(long) not 4 or 8 <<<<< #endif