[Click] Timestamp changes

Eddie Kohler kohler at cs.ucla.edu
Thu Dec 30 18:53:18 EST 2004


Hey all,

I have some probably annoying news.

In the interest of supporting nanosecond-scale timestamps, we've deeply changed 
the way Click handles time values.

In particular, the good old 'struct timeval' is gone.  It was replaced with a 
Click type, 'Timestamp', defined in include/click/timestamp.hh.  Timestamp acts 
like a 'struct timeval' unless you configured with '--enable-nanotimestamp', in 
which case it has nanosecond-scale precision.

Timers are scheduled with Timestamps.  Packet timestamps are Timestamps, not 
'struct timeval's.

This was a big change and may require some time to settle in.  Please feel 
utterly free to report bugs to the list.  Element authors may want to check over 
the attached diff.

Thanks,
Eddie

-------------- next part --------------
? +milk
Index: elements/analysis/aggregateipflows.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/aggregateipflows.cc,v
retrieving revision 1.27
diff -u -u -w -r1.27 aggregateipflows.cc
--- elements/analysis/aggregateipflows.cc	24 Jun 2004 00:03:55 -0000	1.27
+++ elements/analysis/aggregateipflows.cc	30 Dec 2004 23:50:25 -0000
@@ -163,13 +163,13 @@
 	int sport = (ntohl(sinfo->_ports) >> (sinfo->reverse() ? 0 : 16)) & 0xFFFF;
 	IPAddress dst(sinfo->reverse() ? hp.a : hp.b);
 	int dport = (ntohl(sinfo->_ports) >> (sinfo->reverse() ? 16 : 0)) & 0xFFFF;
-	struct timeval duration = sinfo->_last_timestamp - sinfo->_first_timestamp;
-	fprintf(_traceinfo_file, "<flow aggregate='%u' src='%s' sport='%d' dst='%s' dport='%d' begin='%ld.%06ld' duration='%ld.%06ld'",
+	Timestamp duration = sinfo->_last_timestamp - sinfo->_first_timestamp;
+	fprintf(_traceinfo_file, "<flow aggregate='%u' src='%s' sport='%d' dst='%s' dport='%d' begin='" PRITIMESTAMP "' duration='" PRITIMESTAMP "'",
 
 		sinfo->_aggregate,
 		src.s().cc(), sport, dst.s().cc(), dport,
-		sinfo->_first_timestamp.tv_sec, sinfo->_first_timestamp.tv_usec,
-		duration.tv_sec, duration.tv_usec);
+		sinfo->_first_timestamp.sec(), sinfo->_first_timestamp.subsec(),
+		duration.sec(), duration.subsec());
 	if (sinfo->_filepos)
 	    fprintf(_traceinfo_file, " filepos='%u'", sinfo->_filepos);
 	fprintf(_traceinfo_file, ">\n\
@@ -270,7 +270,7 @@
     // emit packets at the beginning of the list that have the same IP ID
     const click_ip *iph;
     while (first && (iph = good_ip_header(first)) && iph->ip_id == want_ip_id
-	   && (SEC_OLDER(first->timestamp_anno().tv_sec, emit_before_sec)
+	   && (SEC_OLDER(first->timestamp_anno().sec(), emit_before_sec)
 	       || !IP_ISFRAG(iph))) {
 	Packet *p = first;
 	hpinfo->_fragment_head = first = p->next();
@@ -310,7 +310,7 @@
     for (Map::iterator iter = table.begin(); iter; iter++) {
 	HostPairInfo *hpinfo = &iter.value();
 	// fragments
-	while (hpinfo->_fragment_head && hpinfo->_fragment_head->timestamp_anno().tv_sec < frag_timeout)
+	while (hpinfo->_fragment_head && hpinfo->_fragment_head->timestamp_anno().sec() < frag_timeout)
 	    assign_aggregate(table, hpinfo, frag_timeout);
 
 	// can't delete any flows if there are fragments
@@ -322,7 +322,7 @@
 	FlowInfo *f = *pprev;
 	while (f) {
 	    // circular comparison
-	    if (SEC_OLDER(f->_last_timestamp.tv_sec, (f->_flow_over == 3 ? done_timeout : timeout))) {
+	    if (SEC_OLDER(f->_last_timestamp.sec(), (f->_flow_over == 3 ? done_timeout : timeout))) {
 		notify(f->_aggregate, AggregateListener::DELETE_AGG, 0);
 		*pprev = f->_next;
 		delete_flowinfo(iter.key(), f);
@@ -384,7 +384,7 @@
 	if (finfo->_ports == ports) {
 	    // if this flow is actually dead (but has not yet been garbage
 	    // collected), then kill it for consistent semantics
-	    int age = p->timestamp_anno().tv_sec - finfo->_last_timestamp.tv_sec;
+	    int age = p->timestamp_anno().sec() - finfo->_last_timestamp.sec();
 	    // 4.Feb.2004 - Also start a new flow if the old flow closed off,
 	    // and we have a SYN.
 	    if ((age > _smallest_timeout
@@ -441,14 +441,14 @@
     p->set_next(0);
     SET_AGGREGATE_ANNO(p, 0);
     SET_PAINT_ANNO(p, paint);
-    if (int p_sec = p->timestamp_anno().tv_sec)
+    if (int p_sec = p->timestamp_anno().sec())
 	_active_sec = p_sec;
 
     // get rid of old fragments
     int frag_timeout = _active_sec - _fragment_timeout;
     Packet *head;
     while ((head = hpinfo->_fragment_head)
-	   && (head->timestamp_anno().tv_sec < frag_timeout || !IP_ISFRAG(good_ip_header(head))))
+	   && (head->timestamp_anno().sec() < frag_timeout || !IP_ISFRAG(good_ip_header(head))))
 	assign_aggregate(table, hpinfo, frag_timeout);
 
     return ACT_NONE;
@@ -461,12 +461,12 @@
     int paint = 0;
 
     // assign timestamp if no timestamp given
-    if (!timerisset(&p->timestamp_anno())) {
+    if (!p->timestamp_anno()) {
 	if (!_timestamp_warning) {
 	    click_chatter("%{element}: warning: packet received without timestamp", this);
 	    _timestamp_warning = true;
 	}
-	click_gettimeofday(&p->timestamp_anno());
+	p->timestamp_anno().set_now();
     }
 	
     // extract encapsulated ICMP header if appropriate
@@ -514,8 +514,8 @@
     }
 
     // mark packet with aggregate number and paint
-    finfo->_last_timestamp.tv_sec = _active_sec = p->timestamp_anno().tv_sec;
-    finfo->_last_timestamp.tv_usec = p->timestamp_anno().tv_usec;
+    _active_sec = p->timestamp_anno().sec();
+    finfo->_last_timestamp = p->timestamp_anno();
     SET_AGGREGATE_ANNO(p, finfo->aggregate());
     if (finfo->reverse())
 	paint ^= 1;
Index: elements/analysis/aggregateipflows.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/aggregateipflows.hh,v
retrieving revision 1.19
diff -u -u -w -r1.19 aggregateipflows.hh
--- elements/analysis/aggregateipflows.hh	3 May 2004 06:04:20 -0000	1.19
+++ elements/analysis/aggregateipflows.hh	30 Dec 2004 23:50:25 -0000
@@ -175,7 +175,7 @@
     struct FlowInfo {
 	uint32_t _ports;
 	uint32_t _aggregate;
-	struct timeval _last_timestamp;
+	Timestamp _last_timestamp;
 	unsigned _flow_over : 2;
 	bool _reverse : 1;
 	FlowInfo *_next;
@@ -187,7 +187,7 @@
     };
 
     struct StatFlowInfo : public FlowInfo {
-	struct timeval _first_timestamp;
+	Timestamp _first_timestamp;
 	uint32_t _filepos;
 	uint32_t _packets[2];
 	StatFlowInfo(uint32_t ports, FlowInfo *next, uint32_t agg) : FlowInfo(ports, next, agg) { _packets[0] = _packets[1] = 0; }
Index: elements/analysis/fromcapdump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromcapdump.cc,v
retrieving revision 1.9
diff -u -u -w -r1.9 fromcapdump.cc
--- elements/analysis/fromcapdump.cc	27 Jul 2004 06:32:57 -0000	1.9
+++ elements/analysis/fromcapdump.cc	30 Dec 2004 23:50:25 -0000
@@ -229,7 +229,7 @@
 	    for (; data < end && isdigit(*data); data++)
 		/* nada */;
 	}
-	q->set_timestamp_anno(u1, u2);
+	q->set_timestamp_anno(Timestamp(u1, u2));
 	data = cp_skip_space(data, end);
 
 	// read sequence numbers and lengths
Index: elements/analysis/fromdagdump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromdagdump.cc,v
retrieving revision 1.24
diff -u -u -w -r1.24 fromdagdump.cc
--- elements/analysis/fromdagdump.cc	3 Sep 2004 18:44:16 -0000	1.24
+++ elements/analysis/fromdagdump.cc	30 Dec 2004 23:50:25 -0000
@@ -65,13 +65,8 @@
 FromDAGDump::configure(Vector<String> &conf, ErrorHandler *errh)
 {
     bool timing = false, stop = false, active = true, force_ip = false;
-    struct timeval first_time, first_time_off, last_time, last_time_off, interval;
+    Timestamp first_time, first_time_off, last_time, last_time_off, interval;
     String encap;
-    timerclear(&first_time);
-    timerclear(&first_time_off);
-    timerclear(&last_time);
-    timerclear(&last_time_off);
-    timerclear(&interval);
     _sampling_prob = (1 << SAMPLING_SHIFT);
 
     if (_ff.configure_keywords(conf, 1, this, errh) < 0)
@@ -82,11 +77,11 @@
 		    "STOP", cpBool, "stop driver when done?", &stop,
 		    "ACTIVE", cpBool, "start active?", &active,
 		    "FORCE_IP", cpBool, "emit IP packets only?", &force_ip,
-		    "START", cpTimeval, "starting time", &first_time,
-		    "START_AFTER", cpTimeval, "starting time offset", &first_time_off,
-		    "END", cpTimeval, "ending time", &last_time,
-		    "END_AFTER", cpTimeval, "ending time offset", &last_time_off,
-		    "INTERVAL", cpTimeval, "time interval", &interval,
+		    "START", cpTimestamp, "starting time", &first_time,
+		    "START_AFTER", cpTimestamp, "starting time offset", &first_time_off,
+		    "END", cpTimestamp, "ending time", &last_time,
+		    "END_AFTER", cpTimestamp, "ending time offset", &last_time_off,
+		    "INTERVAL", cpTimestamp, "time interval", &interval,
 		    "END_CALL", cpWriteHandlerCall, "write handler for ending time", &_end_h,
 		    "SAMPLE", cpUnsignedReal2, "sampling probability", SAMPLING_SHIFT, &_sampling_prob,
 		    "TIMING", cpBool, "use original packet timing?", &timing,
@@ -105,24 +100,22 @@
     _have_first_time = _have_last_time = true;
     _first_time_relative = _last_time_relative = _last_time_interval = false;
     
-    if ((timerisset(&first_time) != 0) + (timerisset(&first_time_off) != 0) > 1)
+    if ((bool) first_time + (bool) first_time_off > 1)
 	return errh->error("'START' and 'START_AFTER' are mutually exclusive");
-    else if (timerisset(&first_time))
+    else if ((bool) first_time)
 	_first_time = first_time;
-    else if (timerisset(&first_time_off))
+    else if ((bool) first_time_off)
 	_first_time = first_time_off, _first_time_relative = true;
-    else {
-	timerclear(&_first_time);
+    else
 	_have_first_time = false, _first_time_relative = true;
-    }
     
-    if ((timerisset(&last_time) != 0) + (timerisset(&last_time_off) != 0) + (timerisset(&interval) != 0) > 1)
+    if ((bool) last_time + (bool) last_time_off + (bool) interval > 1)
 	return errh->error("'END', 'END_AFTER', and 'INTERVAL' are mutually exclusive");
-    else if (timerisset(&last_time))
+    else if ((bool) last_time)
 	_last_time = last_time;
-    else if (timerisset(&last_time_off))
+    else if ((bool) last_time_off)
 	_last_time = last_time_off, _last_time_relative = true;
-    else if (timerisset(&interval))
+    else if ((bool) interval)
 	_last_time = interval, _last_time_interval = true;
     else
 	_have_last_time = false;
@@ -170,11 +163,8 @@
 	return -1;
     
     // try reading a packet
-    if (read_packet(errh)) {
-	struct timeval now;
-	click_gettimeofday(&now);
-	timersub(&now, &_packet->timestamp_anno(), &_time_offset);
-    }
+    if (read_packet(errh))
+	_time_offset = Timestamp::now() - _packet->timestamp_anno();
 
     if (output_is_push(0))
 	ScheduleInfo::initialize_task(this, &_task, _active, errh);
@@ -220,28 +210,29 @@
 }
 
 void
-FromDAGDump::stamp_to_timeval(uint64_t stamp, struct timeval &tv) const
+FromDAGDump::stamp_to_time(uint64_t stamp, Timestamp &tv) const
 {
-    tv.tv_sec = (uint32_t) (stamp >> 32);
+    uint32_t sec = (uint32_t) (stamp >> 32);
     // based on a code description in an Endace document
-    stamp = (stamp & 0xFFFFFFFFULL) * 1000000;
+    stamp = (stamp & 0xFFFFFFFFULL) * 1000000000;
     stamp += (stamp & 0x80000000ULL) << 1; // rounding
-    tv.tv_usec = (uint32_t) (stamp >> 32);
-    if (tv.tv_usec >= 1000000) {
-	tv.tv_usec -= 1000000;
-	tv.tv_sec += 1;
+    uint32_t nsec = (uint32_t) (stamp >> 32);
+    if (nsec >= 1000000000) {
+	nsec -= 1000000000;
+	sec += 1;
     }
+    tv = Timestamp::make_nsec(sec, nsec);
 }
 
 void
-FromDAGDump::prepare_times(struct timeval &tv)
+FromDAGDump::prepare_times(const Timestamp &tv)
 {
     if (_first_time_relative)
-	timeradd(&tv, &_first_time, &_first_time);
+	_first_time += tv;
     if (_last_time_relative)
-	timeradd(&tv, &_last_time, &_last_time);
+	_last_time += tv;
     else if (_last_time_interval)
-	timeradd(&_first_time, &_last_time, &_last_time);
+	_last_time += _first_time;
     _have_any_times = true;
 }
 
@@ -250,7 +241,7 @@
 {
     const DAGCell *cell;
     static DAGCell static_cell;
-    struct timeval tv;
+    Timestamp tv;
     Packet *p;
     bool more = true;
     _packet = 0;
@@ -267,16 +258,16 @@
 
     // check times
   check_times:
-    stamp_to_timeval(swapq(cell->timestamp), tv);
+    stamp_to_time(swapq(cell->timestamp), tv);
     if (!_have_any_times)
 	prepare_times(tv);
     if (_have_first_time) {
-	if (timercmp(&tv, &_first_time, <))
+	if (tv < _first_time)
 	    goto retry;
 	else
 	    _have_first_time = false;
     }
-    if (_have_last_time && !timercmp(&tv, &_last_time, <)) {
+    if (_have_last_time && tv >= _last_time) {
 	_have_last_time = false;
 	(void) _end_h->call_write(errh);
 	if (!_active)
@@ -304,7 +295,7 @@
 	  case FAKE_DLT_ATM_RFC1483:
 	  case FAKE_DLT_PPP:
 	  case FAKE_DLT_PPP_HDLC:
-	    p = _ff.get_packet(DAGCell::CELL_SIZE - DAGCell::HEADER_SIZE, tv.tv_sec, tv.tv_usec, errh);
+	    p = _ff.get_packet(DAGCell::CELL_SIZE - DAGCell::HEADER_SIZE, tv.sec(), tv.subsec(), errh);
 	    break;
 	    
 	  case FAKE_DLT_C_HDLC:
@@ -316,16 +307,16 @@
 	    goto cell;
 
 	  case FAKE_DLT_SUNATM:
-	    p = _ff.get_packet_from_data(reinterpret_cast<const uint8_t*>(cell) + 12, 4, DAGCell::CELL_SIZE - 12, tv.tv_sec, tv.tv_usec, errh);
+	    p = _ff.get_packet_from_data(reinterpret_cast<const uint8_t*>(cell) + 12, 4, DAGCell::CELL_SIZE - 12, tv.sec(), tv.subsec(), errh);
 	    break;
 	    
 	  case FAKE_DLT_EN10MB:
 	    wire_length = htons(*(reinterpret_cast<const uint16_t*>(cell) + 4));
-	    p = _ff.get_packet_from_data(reinterpret_cast<const uint8_t*>(cell) + 10, 6, DAGCell::CELL_SIZE - 10, tv.tv_sec, tv.tv_usec, errh);
+	    p = _ff.get_packet_from_data(reinterpret_cast<const uint8_t*>(cell) + 10, 6, DAGCell::CELL_SIZE - 10, tv.sec(), tv.subsec(), errh);
 	    break;
 	    
 	  default:
-	    p = _ff.get_packet_from_data(reinterpret_cast<const uint8_t*>(cell) + 8, 8, DAGCell::CELL_SIZE - 8, tv.tv_sec, tv.tv_usec, errh);
+	    p = _ff.get_packet_from_data(reinterpret_cast<const uint8_t*>(cell) + 8, 8, DAGCell::CELL_SIZE - 8, tv.sec(), tv.subsec(), errh);
 	    break;
 	}
 
@@ -352,7 +343,7 @@
 	}
 	if (read_length < DAGCell::HEADER_SIZE)
 	    return false;
-	p = _ff.get_packet(read_length - DAGCell::HEADER_SIZE, tv.tv_sec, tv.tv_usec, errh);
+	p = _ff.get_packet(read_length - DAGCell::HEADER_SIZE, tv.sec(), tv.subsec(), errh);
     }
     
     // check packet
@@ -378,15 +369,11 @@
 
     bool more;
     if (_packet || read_packet(0)) {
-	if (_timing) {
-	    struct timeval now;
-	    click_gettimeofday(&now);
-	    timersub(&now, &_time_offset, &now);
-	    if (timercmp(&_packet->timestamp_anno(), &now, >)) {
+	if (_timing
+	    && _packet->timestamp_anno() > Timestamp::now() - _time_offset) {
 		_task.fast_reschedule();
 		return false;
 	    }
-	}
 	output(0).push(_packet);
 	more = read_packet(0);
     } else
@@ -408,13 +395,9 @@
     bool more;
     Packet *p;
     if (_packet || read_packet(0)) {
-	if (_timing) {
-	    struct timeval now;
-	    click_gettimeofday(&now);
-	    timersub(&now, &_time_offset, &now);
-	    if (timercmp(&_packet->timestamp_anno(), &now, >))
+	if (_timing
+	    && _packet->timestamp_anno() > Timestamp::now() - _time_offset)
 		return 0;
-	}
 	p = _packet;
 	more = read_packet(0);
     } else {
@@ -466,9 +449,9 @@
 	fd->router()->please_stop_driver();
 	return 0;
       case H_EXTEND_INTERVAL: {
-	  struct timeval tv;
-	  if (cp_timeval(s, &tv)) {
-	      timeradd(&fd->_last_time, &tv, &fd->_last_time);
+	  Timestamp tv;
+	  if (cp_time(s, &tv)) {
+	      fd->_last_time += tv;
 	      if (fd->_end_h)
 		  fd->_have_last_time = true, fd->set_active(true);
 	      return 0;
Index: elements/analysis/fromdagdump.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromdagdump.hh,v
retrieving revision 1.15
diff -u -u -w -r1.15 fromdagdump.hh
--- elements/analysis/fromdagdump.hh	3 Sep 2004 18:46:24 -0000	1.15
+++ elements/analysis/fromdagdump.hh	30 Dec 2004 23:50:25 -0000
@@ -237,18 +237,18 @@
     int _linktype;
     int _base_linktype;
 
-    struct timeval _first_time;
-    struct timeval _last_time;
+    Timestamp _first_time;
+    Timestamp _last_time;
     HandlerCall *_end_h;
     
     Task _task;
 
-    struct timeval _time_offset;
+    Timestamp _time_offset;
 
     bool read_packet(ErrorHandler *);
 
-    void stamp_to_timeval(uint64_t, struct timeval &) const;
-    void prepare_times(struct timeval &);
+    void stamp_to_time(uint64_t, Timestamp &) const;
+    void prepare_times(const Timestamp &);
 
     static String read_handler(Element *, void *);
     static int write_handler(const String &, Element *, void *, ErrorHandler *);
Index: elements/analysis/fromipsumdump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromipsumdump.cc,v
retrieving revision 1.70
diff -u -u -w -r1.70 fromipsumdump.cc
--- elements/analysis/fromipsumdump.cc	16 Sep 2004 04:46:41 -0000	1.70
+++ elements/analysis/fromipsumdump.cc	30 Dec 2004 23:50:25 -0000
@@ -783,6 +783,16 @@
 		    break;
 		  case W_TIMESTAMP:
 		  case W_FIRST_TIMESTAMP:
+		    u1 = GET4(data);
+		    u2 = GET4(data + 4) * 1000;
+		    data += 8;
+		    break;
+		  case W_NTIMESTAMP:
+		  case W_FIRST_NTIMESTAMP:
+		    u1 = GET4(data);
+		    u2 = GET4(data + 4);
+		    data += 8;
+		    break;
 		  case W_TIMESTAMP_USEC1:
 		    u1 = GET4(data);
 		    u2 = GET4(data + 4);
@@ -861,15 +871,17 @@
 		break;
 
 	      case W_TIMESTAMP:
+	      case W_NTIMESTAMP:
 	      case W_FIRST_TIMESTAMP:
+	      case W_FIRST_NTIMESTAMP:
 		next = cp_unsigned(data, end, 10, &u1);
 		if (next > data) {
 		    data = next;
 		    if (data + 1 < end && *data == '.') {
 			int digit = 0;
-			for (data++; digit < 6 && data < end && isdigit(*data); digit++, data++)
+			for (data++; digit < 9 && data < end && isdigit(*data); digit++, data++)
 			    u2 = (u2 * 10) + *data - '0';
-			for (; digit < 6; digit++)
+			for (; digit < 9; digit++)
 			    u2 = (u2 * 10);
 			for (; data < end && isdigit(*data); data++)
 			    /* nada */;
@@ -1063,28 +1075,29 @@
 	    switch (_contents[i]) {
 
 	      case W_TIMESTAMP:
-		if (u2 < 1000000)
-		    q->set_timestamp_anno(u1, u2), ok++;
+	      case W_NTIMESTAMP:
+		if (u2 < 1000000000)
+		    q->timestamp_anno().set_nsec(u1, u2), ok++;
 		break;
 
 	      case W_TIMESTAMP_SEC:
-		q->timestamp_anno().tv_sec = u1, ok++;
+		q->timestamp_anno().set_sec(u1), ok++;
 		break;
 
 	      case W_TIMESTAMP_USEC:
 		if (u1 < 1000000)
-		    q->timestamp_anno().tv_usec = u1, ok++;
+		    q->timestamp_anno().set_subsec(Timestamp::usec_to_subsec(u1)), ok++;
 		break;
 
 	      case W_TIMESTAMP_USEC1:
 		if (u1 == 0 && u2 < 1000000)
-		    q->set_timestamp_anno(0, u2), ok++;
+		    q->timestamp_anno().set_usec(0, u2), ok++;
 		else if (u1 == 0)
-		    q->set_timestamp_anno(u2/1000000, u2%1000000), ok++;
+		    q->timestamp_anno().set_usec(u2/1000000, u2%1000000), ok++;
 #if HAVE_INT64_TYPES
 		else {
 		    uint64_t uu = ((uint64_t)u1 << 32) | u2;
-		    q->set_timestamp_anno(uu/1000000, uu%1000000), ok++;
+		    q->timestamp_anno().set_usec(uu/1000000, uu%1000000), ok++;
 		}
 #endif
 		break;
@@ -1191,10 +1204,9 @@
 		break;
 
 	      case W_FIRST_TIMESTAMP:
-		if (u2 < 1000000) {
-		    struct timeval tv;
-		    tv.tv_sec = u1; tv.tv_usec = u2;
-		    SET_FIRST_TIMESTAMP_ANNO(q, tv);
+	      case W_FIRST_NTIMESTAMP:
+		if (u2 < 1000000000) {
+		    SET_FIRST_TIMESTAMP_ANNO(q, Timestamp::make_nsec(u1, u2));
 		    ok++;
 		}
 		break;
@@ -1328,11 +1340,11 @@
 	}
 	// set timestamps
 	_multipacket_end_timestamp = p->timestamp_anno();
-	if (timerisset(&FIRST_TIMESTAMP_ANNO(p))) {
+	if (FIRST_TIMESTAMP_ANNO(p)) {
 	    _multipacket_timestamp_delta = (p->timestamp_anno() - FIRST_TIMESTAMP_ANNO(p)) / (count - 1);
 	    p->timestamp_anno() = FIRST_TIMESTAMP_ANNO(p);
 	} else
-	    _multipacket_timestamp_delta = make_timeval(0, 0);
+	    _multipacket_timestamp_delta = Timestamp();
 	// prepare IP lengths for _multipacket_extra_length
 	_work_packet = set_packet_lengths(p, _multipacket_length - p->length());
 	if (!_work_packet)
Index: elements/analysis/fromipsumdump.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromipsumdump.hh,v
retrieving revision 1.38
diff -u -u -w -r1.38 fromipsumdump.hh
--- elements/analysis/fromipsumdump.hh	20 Aug 2004 01:50:40 -0000	1.38
+++ elements/analysis/fromipsumdump.hh	30 Dec 2004 23:50:25 -0000
@@ -186,8 +186,8 @@
     bool _binary : 1;
     Packet *_work_packet;
     uint32_t _multipacket_length;
-    struct timeval _multipacket_timestamp_delta;
-    struct timeval _multipacket_end_timestamp;
+    Timestamp _multipacket_timestamp_delta;
+    Timestamp _multipacket_end_timestamp;
 
     Task _task;
     ActiveNotifier _notifier;
Index: elements/analysis/fromnetflowsumdump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromnetflowsumdump.cc,v
retrieving revision 1.21
diff -u -u -w -r1.21 fromnetflowsumdump.cc
--- elements/analysis/fromnetflowsumdump.cc	17 Sep 2004 03:02:43 -0000	1.21
+++ elements/analysis/fromnetflowsumdump.cc	30 Dec 2004 23:50:26 -0000
@@ -180,12 +180,12 @@
 
 	// annotations
 	if (cp_unsigned(words[7], &j))
-	    SET_FIRST_TIMESTAMP_ANNO(q, make_timeval(j, 0)), ok++;
+	    SET_FIRST_TIMESTAMP_ANNO(q, Timestamp(j, 0)), ok++;
 	if (cp_unsigned(words[8], &j)) {
 	    if (j)
-		q->set_timestamp_anno(j, 0);
+		q->timestamp_anno().set(j, 0);
 	    else
-		q->set_timestamp_anno(FIRST_TIMESTAMP_ANNO(q));
+		q->timestamp_anno() = FIRST_TIMESTAMP_ANNO(q);
 	    ok++;
 	}
 	if (cp_unsigned(words[5], &j))
@@ -288,11 +288,11 @@
 	}
 	// set timestamps
 	_multipacket_end_timestamp = p->timestamp_anno();
-	if (timerisset(&FIRST_TIMESTAMP_ANNO(p))) {
+	if (FIRST_TIMESTAMP_ANNO(p)) {
 	    _multipacket_timestamp_delta = (p->timestamp_anno() - FIRST_TIMESTAMP_ANNO(p)) / (count - 1);
 	    p->timestamp_anno() = FIRST_TIMESTAMP_ANNO(p);
 	} else
-	    _multipacket_timestamp_delta = make_timeval(0, 0);
+	    _multipacket_timestamp_delta = Timestamp();
 	// prepare IP lengths for _multipacket_length
 	_work_packet = set_packet_lengths(p, _multipacket_length - p->length());
 	if (!_work_packet)
Index: elements/analysis/fromnetflowsumdump.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromnetflowsumdump.hh,v
retrieving revision 1.17
diff -u -u -w -r1.17 fromnetflowsumdump.hh
--- elements/analysis/fromnetflowsumdump.hh	17 Sep 2004 03:02:43 -0000	1.17
+++ elements/analysis/fromnetflowsumdump.hh	30 Dec 2004 23:50:26 -0000
@@ -153,13 +153,13 @@
     uint8_t _link;
     Packet *_work_packet;
     uint32_t _multipacket_length;
-    struct timeval _multipacket_timestamp_delta;
-    struct timeval _multipacket_end_timestamp;
+    Timestamp _multipacket_timestamp_delta;
+    Timestamp _multipacket_end_timestamp;
 
     Task _task;
     ActiveNotifier _notifier;
 
-    struct timeval _time_offset;
+    Timestamp _time_offset;
 
     Packet *read_packet(ErrorHandler *);
     Packet *handle_multipacket(Packet *);
Index: elements/analysis/fromnlanrdump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromnlanrdump.cc,v
retrieving revision 1.7
diff -u -u -w -r1.7 fromnlanrdump.cc
--- elements/analysis/fromnlanrdump.cc	17 Sep 2004 03:02:43 -0000	1.7
+++ elements/analysis/fromnlanrdump.cc	30 Dec 2004 23:50:26 -0000
@@ -65,12 +65,7 @@
 {
     bool timing = false, stop = false, active = true;
     String format = "guess";
-    struct timeval first_time, first_time_off, last_time, last_time_off, interval;
-    timerclear(&first_time);
-    timerclear(&first_time_off);
-    timerclear(&last_time);
-    timerclear(&last_time_off);
-    timerclear(&interval);
+    Timestamp first_time, first_time_off, last_time, last_time_off, interval;
     _sampling_prob = (1 << SAMPLING_SHIFT);
     _packet_filepos = 0;
     bool force_ip = true;
@@ -84,11 +79,11 @@
 		    "STOP", cpBool, "stop driver when done?", &stop,
 		    "ACTIVE", cpBool, "start active?", &active,
 		    "FORCE_IP", cpBool, "ignored for compatibility", &force_ip,
-		    "START", cpTimeval, "starting time", &first_time,
-		    "START_AFTER", cpTimeval, "starting time offset", &first_time_off,
-		    "END", cpTimeval, "ending time", &last_time,
-		    "END_AFTER", cpTimeval, "ending time offset", &last_time_off,
-		    "INTERVAL", cpTimeval, "time interval", &interval,
+		    "START", cpTimestamp, "starting time", &first_time,
+		    "START_AFTER", cpTimestamp, "starting time offset", &first_time_off,
+		    "END", cpTimestamp, "ending time", &last_time,
+		    "END_AFTER", cpTimestamp, "ending time offset", &last_time_off,
+		    "INTERVAL", cpTimestamp, "time interval", &interval,
 		    "END_CALL", cpWriteHandlerCall, "write handler for ending time", &_end_h,
 		    "FILEPOS", cpFileOffset, "starting file position", &_packet_filepos,
 		    "SAMPLE", cpUnsignedReal2, "sampling probability", SAMPLING_SHIFT, &_sampling_prob,
@@ -107,24 +102,22 @@
     _have_first_time = _have_last_time = true;
     _first_time_relative = _last_time_relative = _last_time_interval = false;
     
-    if ((timerisset(&first_time) != 0) + (timerisset(&first_time_off) != 0) > 1)
+    if ((bool) first_time + (bool) first_time_off > 1)
 	return errh->error("'START' and 'START_AFTER' are mutually exclusive");
-    else if (timerisset(&first_time))
+    else if (first_time)
 	_first_time = first_time;
-    else if (timerisset(&first_time_off))
+    else if (first_time_off)
 	_first_time = first_time_off, _first_time_relative = true;
-    else {
-	timerclear(&_first_time);
+    else
 	_have_first_time = false, _first_time_relative = true;
-    }
     
-    if ((timerisset(&last_time) != 0) + (timerisset(&last_time_off) != 0) + (timerisset(&interval) != 0) > 1)
+    if ((bool) last_time + (bool) last_time_off + (bool) interval > 1)
 	return errh->error("'END', 'END_AFTER', and 'INTERVAL' are mutually exclusive");
-    else if (timerisset(&last_time))
+    else if (last_time)
 	_last_time = last_time;
-    else if (timerisset(&last_time_off))
+    else if (last_time_off)
 	_last_time = last_time_off, _last_time_relative = true;
-    else if (timerisset(&interval))
+    else if (interval)
 	_last_time = interval, _last_time_interval = true;
     else
 	_have_last_time = false;
@@ -191,11 +184,8 @@
 	return -1;
     
     // try reading a packet
-    if (read_packet(errh)) {
-	struct timeval now;
-	click_gettimeofday(&now);
-	timersub(&now, &_packet->timestamp_anno(), &_time_offset);
-    }
+    if (read_packet(errh))
+	_time_offset = Timestamp::now() - _packet->timestamp_anno();
 
     // maybe skip ahead in the file
     if (_packet_filepos != 0) {
@@ -226,14 +216,14 @@
 }
 
 void
-FromNLANRDump::prepare_times(struct timeval &tv)
+FromNLANRDump::prepare_times(const Timestamp &tv)
 {
     if (_first_time_relative)
-	timeradd(&tv, &_first_time, &_first_time);
+	_first_time += tv;
     if (_last_time_relative)
-	timeradd(&tv, &_last_time, &_last_time);
+	_last_time += tv;
     else if (_last_time_interval)
-	timeradd(&_first_time, &_last_time, &_last_time);
+	_last_time += _first_time;
     _have_any_times = true;
 }
 
@@ -242,7 +232,7 @@
 {
     const TSHCell *cell;
     static TSHCell static_cell;
-    struct timeval tv;
+    Timestamp tv;
     Packet *p;
     bool more = true;
     _packet = 0;
@@ -264,18 +254,18 @@
   check_times:
     uint32_t usec = ntohl(cell->timestamp_usec);
     if (_format == C_TSH)
-	tv = make_timeval(ntohl(cell->timestamp_sec), usec & 0xFFFFFF);
+	tv = Timestamp(ntohl(cell->timestamp_sec), usec & 0xFFFFFF);
     else if (_format == C_FRPLUS || _format == C_FR)
-	tv = make_timeval(ntohl(cell->timestamp_sec), usec);
+	tv = Timestamp(ntohl(cell->timestamp_sec), usec);
     if (!_have_any_times)
 	prepare_times(tv);
     if (_have_first_time) {
-	if (timercmp(&tv, &_first_time, <))
+	if (tv < _first_time)
 	    goto retry;
 	else
 	    _have_first_time = false;
     }
-    if (_have_last_time && !timercmp(&tv, &_last_time, <)) {
+    if (_have_last_time && tv >= _last_time) {
 	_have_last_time = false;
 	(void) _end_h->call_write(errh);
 	if (!_active)
@@ -295,7 +285,7 @@
     
     // create packet
     if (_format != C_FR)
-	p = _ff.get_packet_from_data(&cell->iph, _cell_size - 8, _cell_size - 8, tv.tv_sec, tv.tv_usec, errh);
+	p = _ff.get_packet_from_data(&cell->iph, _cell_size - 8, _cell_size - 8, tv.sec(), tv.subsec(), errh);
     else
 	p = 0;
     if (!p)
@@ -321,15 +311,11 @@
 
     bool more;
     if (_packet || read_packet(0)) {
-	if (_timing) {
-	    struct timeval now;
-	    click_gettimeofday(&now);
-	    timersub(&now, &_time_offset, &now);
-	    if (timercmp(&_packet->timestamp_anno(), &now, >)) {
+	if (_timing
+	    && _packet->timestamp_anno() > Timestamp::now() - _time_offset) {
 		_task.fast_reschedule();
 		return false;
 	    }
-	}
 	output(0).push(_packet);
 	more = read_packet(0);
     } else
@@ -351,13 +337,9 @@
     bool more;
     Packet *p;
     if (_packet || read_packet(0)) {
-	if (_timing) {
-	    struct timeval now;
-	    click_gettimeofday(&now);
-	    timersub(&now, &_time_offset, &now);
-	    if (timercmp(&_packet->timestamp_anno(), &now, >))
+	if (_timing
+	    && _packet->timestamp_anno() > Timestamp::now() - _time_offset)
 		return 0;
-	}
 	p = _packet;
 	more = read_packet(0);
     } else {
@@ -412,9 +394,9 @@
 	fd->router()->please_stop_driver();
 	return 0;
       case H_EXTEND_INTERVAL: {
-	  struct timeval tv;
-	  if (cp_timeval(s, &tv)) {
-	      timeradd(&fd->_last_time, &tv, &fd->_last_time);
+	  Timestamp tv;
+	  if (cp_time(s, &tv)) {
+	      fd->_last_time += tv;
 	      if (fd->_end_h)
 		  fd->_have_last_time = true, fd->set_active(true);
 	      return 0;
Index: elements/analysis/fromnlanrdump.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromnlanrdump.hh,v
retrieving revision 1.5
diff -u -u -w -r1.5 fromnlanrdump.hh
--- elements/analysis/fromnlanrdump.hh	17 Sep 2004 03:02:43 -0000	1.5
+++ elements/analysis/fromnlanrdump.hh	30 Dec 2004 23:50:26 -0000
@@ -234,18 +234,18 @@
     int _format;
     int _cell_size;
 
-    struct timeval _first_time;
-    struct timeval _last_time;
+    Timestamp _first_time;
+    Timestamp _last_time;
     HandlerCall *_end_h;
     
     Task _task;
 
-    struct timeval _time_offset;
+    Timestamp _time_offset;
     off_t _packet_filepos;
 
     bool read_packet(ErrorHandler *);
 
-    void prepare_times(struct timeval &);
+    void prepare_times(const Timestamp &);
 
     static String read_handler(Element *, void *);
     static int write_handler(const String &, Element *, void *, ErrorHandler *);
Index: elements/analysis/fromtcpdump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/fromtcpdump.cc,v
retrieving revision 1.10
diff -u -u -w -r1.10 fromtcpdump.cc
--- elements/analysis/fromtcpdump.cc	16 Sep 2004 04:46:41 -0000	1.10
+++ elements/analysis/fromtcpdump.cc	30 Dec 2004 23:50:26 -0000
@@ -395,7 +395,7 @@
 
 	// first, read timestamp
 	const char *s2 = find(s, end, ' ');
-	if (!cp_timeval(line.substring(s, s2), &q->timestamp_anno()))
+	if (!cp_time(line.substring(s, s2), &q->timestamp_anno()))
 	    break;
 	s = s2 + 1;
 
Index: elements/analysis/ipsumdump_anno.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/ipsumdump_anno.cc,v
retrieving revision 1.3
diff -u -u -w -r1.3 ipsumdump_anno.cc
--- elements/analysis/ipsumdump_anno.cc	17 Sep 2004 03:12:42 -0000	1.3
+++ elements/analysis/ipsumdump_anno.cc	30 Dec 2004 23:50:26 -0000
@@ -34,31 +34,31 @@
     Packet *p = d.p;
     switch (thunk & ~B_TYPEMASK) {
       case T_TIMESTAMP:
-	d.v = p->timestamp_anno().tv_sec;
-	d.v2 = p->timestamp_anno().tv_usec;
+	d.v = p->timestamp_anno().sec();
+	d.v2 = p->timestamp_anno().nsec();
 	return true;
       case T_TIMESTAMP_SEC:
-	d.v = p->timestamp_anno().tv_sec;
+	d.v = p->timestamp_anno().sec();
 	return true;
       case T_TIMESTAMP_USEC:
-	d.v = p->timestamp_anno().tv_usec;
+	d.v = p->timestamp_anno().usec();
 	return true;
       case T_TIMESTAMP_USEC1: {
 #if HAVE_INT64_TYPES
-	  uint64_t v3 = ((uint64_t)p->timestamp_anno().tv_sec * 1000000) + p->timestamp_anno().tv_usec;
+	  uint64_t v3 = ((uint64_t)p->timestamp_anno().sec() * 1000000) + p->timestamp_anno().usec();
 	  d.v = v3 >> 32;
 	  d.v2 = v3;
 	  return true;
 #else
 	  // XXX silently output garbage if 64-bit ints not supported
 	  d.v = 0;
-	  d.v2 = (p->timestamp_anno().tv_sec * 1000000) + p->timestamp_anno().tv_usec;
+	  d.v2 = (p->timestamp_anno().sec() * 1000000) + p->timestamp_anno().usec();
 	  return true;
 #endif
       }
       case T_FIRST_TIMESTAMP:
-	d.v = FIRST_TIMESTAMP_ANNO(p).tv_sec;
-	d.v2 = FIRST_TIMESTAMP_ANNO(p).tv_usec;
+	d.v = FIRST_TIMESTAMP_ANNO(p).sec();
+	d.v2 = FIRST_TIMESTAMP_ANNO(p).nsec();
 	return true;
       case T_COUNT:
 	d.v = 1 + EXTRA_PACKETS_ANNO(p);
@@ -79,11 +79,9 @@
 {
     switch (thunk & ~B_TYPEMASK) {
       case T_TIMESTAMP:
-      case T_FIRST_TIMESTAMP: {
-	  timeval tv = make_timeval(d.v, d.v2);
-	  *d.sa << tv;
+      case T_FIRST_TIMESTAMP:
+	*d.sa << Timestamp::make_nsec(d.v, d.v2);
 	  break;
-      }
       case T_TIMESTAMP_USEC1:
 #if HAVE_INT64_TYPES
 	*d.sa << (((uint64_t)d.v) << 32) | d.v2;
@@ -102,23 +100,40 @@
     }
 }
 
+#ifdef i386
+# define PUT4(p, d)	*reinterpret_cast<uint32_t *>((p)) = htonl((d))
+#else
+# define PUT4(p, d)	do { (p)[0] = (d)>>24; (p)[1] = (d)>>16; (p)[2] = (d)>>8; (p)[3] = (d); } while (0)
+#endif
+
+static void timestamp_outb(const PacketDesc& d, bool, int)
+{
+    char* c = d.sa->extend(8);
+    PUT4(c, d.v);
+    PUT4(c + 4, d.v2 / 1000);
+}
+
 void anno_register_unparsers()
 {
-    register_unparser("timestamp", T_TIMESTAMP | B_8, 0, anno_extract, anno_outa, outb);
+    register_unparser("timestamp", T_TIMESTAMP | B_8, 0, anno_extract, anno_outa, timestamp_outb);
+    register_unparser("ntimestamp", T_TIMESTAMP | B_8, 0, anno_extract, anno_outa, outb);
     register_unparser("ts_sec", T_TIMESTAMP_SEC | B_4, 0, anno_extract, num_outa, outb);
     register_unparser("ts_usec", T_TIMESTAMP_USEC | B_4, 0, anno_extract, num_outa, outb);
     register_unparser("ts_usec1", T_TIMESTAMP_USEC1 | B_8, 0, anno_extract, anno_outa, outb);
-    register_unparser("first_timestamp", T_FIRST_TIMESTAMP | B_8, 0, anno_extract, anno_outa, outb);
+    register_unparser("first_timestamp", T_FIRST_TIMESTAMP | B_8, 0, anno_extract, anno_outa, timestamp_outb);
+    register_unparser("first_ntimestamp", T_FIRST_TIMESTAMP | B_8, 0, anno_extract, anno_outa, outb);
     register_unparser("count", T_COUNT | B_4, 0, anno_extract, num_outa, outb);
     register_unparser("link", T_LINK | B_1, 0, anno_extract, num_outa, outb);
     register_unparser("direction", T_DIRECTION | B_1, 0, anno_extract, anno_outa, outb);
     register_unparser("aggregate", T_AGGREGATE | B_4, 0, anno_extract, num_outa, outb);
     
-    register_synonym("ts", "timestamp");
+    register_synonym("utimestamp", "timestamp");
+    register_synonym("ts", "utimestamp");
     register_synonym("sec", "ts_sec");
     register_synonym("usec", "ts_usec");
     register_synonym("usec1", "ts_usec1");
-    register_synonym("first_ts", "first_timestamp");
+    register_synonym("first_utimestamp", "first_timestamp");
+    register_synonym("first_ts", "first_utimestamp");
     register_synonym("pkt_count", "count");
     register_synonym("packet_count", "count");
     register_synonym("agg", "aggregate");
Index: elements/analysis/ipsumdumpinfo.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/ipsumdumpinfo.cc,v
retrieving revision 1.19
diff -u -u -w -r1.19 ipsumdumpinfo.cc
--- elements/analysis/ipsumdumpinfo.cc	17 Sep 2004 03:12:42 -0000	1.19
+++ elements/analysis/ipsumdumpinfo.cc	30 Dec 2004 23:50:26 -0000
@@ -77,6 +77,10 @@
 	return W_AGGREGATE;
     else if (word == "first_timestamp" || word == "first_ts")
 	return W_FIRST_TIMESTAMP;
+    else if (word == "ntimestamp")
+	return W_NTIMESTAMP;
+    else if (word == "first_ntimestamp")
+	return W_FIRST_NTIMESTAMP;
     else if (word == "tcp_window" || word == "tcp_win")
 	return W_TCP_WINDOW;
     else if (word == "ip_opt")
@@ -108,7 +112,8 @@
 			// W_FIRST_TIMESTAMP
     2, 4, 1, 1, 8,	// W_TCP_WINDOW, W_IP_OPT, W_IP_TOS, W_IP_TTL,
     			// W_TIMESTAMP_USEC1
-    4, 2		// W_IP_CAPTURE_LEN, W_TCP_URP
+    4, 2, 8, 8		// W_IP_CAPTURE_LEN, W_TCP_URP, W_NTIMESTAMP,
+			// W_FIRST_NTIMESTAMP
 };
 
 int
Index: elements/analysis/ipsumdumpinfo.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/ipsumdumpinfo.hh,v
retrieving revision 1.14
diff -u -u -w -r1.14 ipsumdumpinfo.hh
--- elements/analysis/ipsumdumpinfo.hh	17 Sep 2004 03:12:42 -0000	1.14
+++ elements/analysis/ipsumdumpinfo.hh	30 Dec 2004 23:50:26 -0000
@@ -122,7 +122,7 @@
     W_COUNT, W_IP_FRAG, W_IP_FRAGOFF, W_PAYLOAD, W_LINK,
     W_AGGREGATE, W_TCP_SACK, W_TCP_OPT, W_TCP_NTOPT, W_FIRST_TIMESTAMP,
     W_TCP_WINDOW, W_IP_OPT, W_IP_TOS, W_IP_TTL, W_TIMESTAMP_USEC1,
-    W_IP_CAPTURE_LEN, W_TCP_URP, W_LAST
+    W_IP_CAPTURE_LEN, W_TCP_URP, W_NTIMESTAMP, W_FIRST_NTIMESTAMP, W_LAST
 };
 static int parse_content(const String &);
 static int content_binary_size(int);
Index: elements/analysis/settimestampdelta.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/settimestampdelta.cc,v
retrieving revision 1.1
diff -u -u -w -r1.1 settimestampdelta.cc
--- elements/analysis/settimestampdelta.cc	2 Dec 2003 19:22:28 -0000	1.1
+++ elements/analysis/settimestampdelta.cc	30 Dec 2004 23:50:26 -0000
@@ -27,7 +27,6 @@
     : Element(1, 1)
 {
     MOD_INC_USE_COUNT;
-    timerclear(&_first);
 }
 
 SetTimestampDelta::~SetTimestampDelta()
@@ -38,9 +37,9 @@
 Packet *
 SetTimestampDelta::simple_action(Packet *p)
 {
-    struct timeval &tv = p->timestamp_anno();
-    if (timerisset(&tv)) {
-	if (!timerisset(&_first))
+    Timestamp& tv = p->timestamp_anno();
+    if (tv) {
+	if (!_first)
 	    _first = tv;
 	tv -= _first;
     }
@@ -67,7 +66,7 @@
 SetTimestampDelta::write_handler(const String &, Element *e, void *, ErrorHandler *)
 {
     SetTimestampDelta *td = static_cast<SetTimestampDelta *>(e);
-    timerclear(&td->_first);
+    td->_first = Timestamp();
     return 0;
 }
 
Index: elements/analysis/settimestampdelta.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/settimestampdelta.hh,v
retrieving revision 1.2
diff -u -u -w -r1.2 settimestampdelta.hh
--- elements/analysis/settimestampdelta.hh	3 May 2004 06:04:20 -0000	1.2
+++ elements/analysis/settimestampdelta.hh	30 Dec 2004 23:50:26 -0000
@@ -47,7 +47,7 @@
     
   private:
 
-    struct timeval _first;
+    Timestamp _first;
 
     static String read_handler(Element *, void *);
     static int write_handler(const String &, Element *, void *, ErrorHandler*);
Index: elements/analysis/timefilter.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/timefilter.cc,v
retrieving revision 1.10
diff -u -u -w -r1.10 timefilter.cc
--- elements/analysis/timefilter.cc	24 Jun 2004 00:03:55 -0000	1.10
+++ elements/analysis/timefilter.cc	30 Dec 2004 23:50:26 -0000
@@ -45,25 +45,18 @@
 int
 TimeFilter::configure(Vector<String> &conf, ErrorHandler *errh)
 {
-    struct timeval first, last, first_init, last_init, first_delta, last_delta, interval;
-    timerclear(&first);
-    timerclear(&last);
-    timerclear(&first_init);
-    timerclear(&last_init);
-    timerclear(&first_delta);
-    timerclear(&last_delta);
-    timerclear(&interval);
+    Timestamp first, last, first_init, last_init, first_delta, last_delta, interval;
     bool stop = false;
 
     if (cp_va_parse(conf, this, errh,
 		    cpKeywords,
-		    "START", cpTimeval, "start time", &first,
-		    "END", cpTimeval, "end time", &last,
-		    "START_DELAY", cpTimeval, "start T after initialization", &first_init,
-		    "END_DELAY", cpTimeval, "end T after initialization", &last_init,
-		    "START_AFTER", cpTimeval, "start T after first packet", &first_delta,
-		    "END_AFTER", cpTimeval, "end T after first packet", &last_delta,
-		    "INTERVAL", cpTimeval, "interval", &interval,
+		    "START", cpTimestamp, "start time", &first,
+		    "END", cpTimestamp, "end time", &last,
+		    "START_DELAY", cpTimestamp, "start T after initialization", &first_init,
+		    "END_DELAY", cpTimestamp, "end T after initialization", &last_init,
+		    "START_AFTER", cpTimestamp, "start T after first packet", &first_delta,
+		    "END_AFTER", cpTimestamp, "end T after first packet", &last_delta,
+		    "INTERVAL", cpTimestamp, "interval", &interval,
 		    "STOP", cpBool, "stop when after end?", &stop,
 		    "END_CALL", cpWriteHandlerCall, "handler to call at end", &_last_h,
 		    cpEnd) < 0)
@@ -71,30 +64,30 @@
 
     _first_relative = _first_init_relative = _last_relative = _last_init_relative = _last_interval = false;
     
-    if ((timerisset(&first) != 0) + (timerisset(&first_delta) != 0) + (timerisset(&first_init) != 0) > 1)
-	return errh->error("`START', `START_AFTER', and `START_AFTER_INIT' are mutually exclusive");
-    else if (timerisset(&first))
+    if ((bool) first + (bool) first_delta + (bool) first_init > 1)
+	return errh->error("'START', 'START_AFTER', and 'START_AFTER_INIT' are mutually exclusive");
+    else if (first)
 	_first = first;
-    else if (timerisset(&first_init))
+    else if (first_init)
 	_first = first_init, _first_init_relative = true;
     else
 	_first = first_delta, _first_relative = true;
     
-    if ((timerisset(&last) != 0) + (timerisset(&last_delta) != 0) + (timerisset(&last_init) != 0) + (timerisset(&interval) != 0) > 1)
-	return errh->error("`END', `END_AFTER', `END_AFTER_INIT', and `INTERVAL'\nare mutually exclusive");
-    else if (timerisset(&last))
+    if ((bool) last + (bool) last_delta + (bool) last_init + (bool) interval > 1)
+	return errh->error("'END', 'END_AFTER', 'END_AFTER_INIT', and 'INTERVAL'\nare mutually exclusive");
+    else if (last)
 	_last = last;
-    else if (timerisset(&last_delta))
+    else if (last_delta)
 	_last = last_delta, _last_relative = true;
-    else if (timerisset(&last_init))
+    else if (last_init)
 	_last = last_init, _last_init_relative = true;
-    else if (timerisset(&interval))
+    else if (interval)
 	_last = interval, _last_interval = true;
     else
-	_last.tv_sec = 0x7FFFFFFF;
+	_last.set_sec(0x7FFFFFFF);
 
     if (_last_h && stop)
-	return errh->error("`END_CALL' and `STOP' are mutually exclusive");
+	return errh->error("'END_CALL' and 'STOP' are mutually exclusive");
     else if (stop)
 	_last_h = new HandlerCall("stop true");
     
@@ -108,26 +101,25 @@
     if (_last_h && _last_h->initialize_write(this, errh) < 0)
 	return -1;
     if (_first_init_relative || _last_init_relative) {
-	struct timeval now;
-	click_gettimeofday(&now);
+	Timestamp now = Timestamp::now();
 	if (_first_init_relative)
-	    timeradd(&_first, &_first, &now);
+	    _first += now;
 	if (_last_init_relative)
-	    timeradd(&_last, &_last, &now);
+	    _last += now;
     }
     _last_h_ready = (_last_h != 0);
     return 0;
 }
 
 void
-TimeFilter::first_packet(const struct timeval &tv)
+TimeFilter::first_packet(const Timestamp& tv)
 {
     if (_first_relative)
-	timeradd(&tv, &_first, &_first);
+	_first += tv;
     if (_last_relative)
-	timeradd(&tv, &_last, &_last);
+	_last += tv;
     else if (_last_interval)
-	timeradd(&_first, &_last, &_last);
+	_last += _first;
     _ready = true;
 }
 
@@ -141,12 +133,12 @@
 Packet *
 TimeFilter::simple_action(Packet *p)
 {
-    const struct timeval &tv = p->timestamp_anno();
+    const Timestamp& tv = p->timestamp_anno();
     if (!_ready)
 	first_packet(tv);
-    if (timercmp(&tv, &_first, <))
+    if (tv < _first)
 	return kill(p);
-    else if (timercmp(&tv, &_last, <))
+    else if (tv < _last)
 	return p;
     else {
 	if (_last_h && _last_h_ready) {
@@ -167,14 +159,14 @@
     String s = cp_uncomment(s_in);
     switch ((intptr_t)thunk) {
       case H_EXTEND_INTERVAL: {
-	  struct timeval tv;
-	  if (cp_timeval(s, &tv)) {
-	      timeradd(&tf->_last, &tv, &tf->_last);
+	  Timestamp t;
+	  if (cp_time(s, &t)) {
+	      tf->_last += t;
 	      if (tf->_last_h)
 		  tf->_last_h_ready = true;
 	      return 0;
 	  } else
-	      return errh->error("`extend_interval' takes a time interval");
+	      return errh->error("'extend_interval' takes a time interval");
       }
       default:
 	return -EINVAL;
Index: elements/analysis/timefilter.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/timefilter.hh,v
retrieving revision 1.10
diff -u -u -w -r1.10 timefilter.hh
--- elements/analysis/timefilter.hh	3 May 2004 06:04:20 -0000	1.10
+++ elements/analysis/timefilter.hh	30 Dec 2004 23:50:26 -0000
@@ -94,8 +94,8 @@
     
   private:
 
-    struct timeval _first;
-    struct timeval _last;
+    Timestamp _first;
+    Timestamp _last;
     
     bool _ready : 1;
     bool _first_relative : 1;
@@ -106,7 +106,7 @@
     bool _last_h_ready : 1;
     HandlerCall *_last_h;
 
-    void first_packet(const struct timeval &);
+    void first_packet(const Timestamp&);
     Packet *kill(Packet *);
 
     static int write_handler(const String &, Element *, void*, ErrorHandler *);
Index: elements/analysis/timerange.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/timerange.cc,v
retrieving revision 1.5
diff -u -u -w -r1.5 timerange.cc
--- elements/analysis/timerange.cc	24 Jun 2004 00:03:55 -0000	1.5
+++ elements/analysis/timerange.cc	30 Dec 2004 23:50:26 -0000
@@ -43,22 +43,20 @@
 		    "SIMPLE", cpBool, "timestamps arrive in increasing order?", &_simple,
 		    cpEnd) < 0)
 	return -1;
-    timerclear(&_first);
-    timerclear(&_last);
     return 0;
 }
 
 Packet *
 TimeRange::simple_action(Packet *p)
 {
-    const struct timeval &tv = p->timestamp_anno();
-    if (!timerisset(&_first))
+    const Timestamp& tv = p->timestamp_anno();
+    if (!_first)
 	_first = _last = tv;
     else if (_simple)
 	_last = tv;
-    else if (timercmp(&_last, &tv, <))
+    else if (_last < tv)
 	_last = tv;
-    else if (timercmp(&tv, &_first, <))
+    else if (tv < _first)
 	_first = tv;
     return p;
 }
@@ -78,12 +76,9 @@
       case 2:
 	sa << tr->_first << ' ' << tr->_last;
 	break;
-      case 3: {
-	  struct timeval tv;
-	  timersub(&tr->_last, &tr->_first, &tv);
-	  sa << tv;
+      case 3:
+	sa << (tr->_last - tr->_first);
 	  break;
-      }
       default:
 	sa << "<error>";
     }
@@ -95,8 +90,7 @@
 TimeRange::write_handler(const String &, Element *e, void *, ErrorHandler *)
 {
     TimeRange *tr = static_cast<TimeRange *>(e);
-    timerclear(&tr->_first);
-    timerclear(&tr->_last);
+    tr->_first = tr->_last = Timestamp();
     return 0;
 }
 
Index: elements/analysis/timerange.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/timerange.hh,v
retrieving revision 1.6
diff -u -u -w -r1.6 timerange.hh
--- elements/analysis/timerange.hh	3 May 2004 06:04:20 -0000	1.6
+++ elements/analysis/timerange.hh	30 Dec 2004 23:50:26 -0000
@@ -69,8 +69,8 @@
     
   private:
 
-    struct timeval _first;
-    struct timeval _last;
+    Timestamp _first;
+    Timestamp _last;
     
     bool _simple;
 
Index: elements/analysis/timesortedsched.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/timesortedsched.cc,v
retrieving revision 1.5
diff -u -u -w -r1.5 timesortedsched.cc
--- elements/analysis/timesortedsched.cc	25 Sep 2004 23:07:38 -0000	1.5
+++ elements/analysis/timesortedsched.cc	30 Dec 2004 23:50:26 -0000
@@ -96,7 +96,7 @@
 TimeSortedSched::pull(int)
 {
     int which = -1;
-    struct timeval* tv = 0;
+    Timestamp* tv = 0;
     bool signals_on = false;
     
     for (int i = 0; i < ninputs(); i++) {
@@ -105,8 +105,8 @@
 	    signals_on = true;
 	}
 	if (_vec[i]) {
-	    struct timeval *this_tv = &_vec[i]->timestamp_anno();
-	    if (!tv || timercmp(this_tv, tv, <)) {
+	    Timestamp* this_tv = &_vec[i]->timestamp_anno();
+	    if (!tv || *this_tv < *tv) {
 		which = i;
 		tv = this_tv;
 	    }
Index: elements/analysis/timestampaccum.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/timestampaccum.cc,v
retrieving revision 1.2
diff -u -u -w -r1.2 timestampaccum.cc
--- elements/analysis/timestampaccum.cc	6 Aug 2002 00:51:24 -0000	1.2
+++ elements/analysis/timestampaccum.cc	30 Dec 2004 23:50:26 -0000
@@ -43,9 +43,7 @@
 inline Packet *
 TimestampAccum::simple_action(Packet *p)
 {
-    struct timeval now;
-    click_gettimeofday(&now);
-    _usec_accum += (now.tv_sec - p->timestamp_anno().tv_sec) + (now.tv_usec - p->timestamp_anno().tv_usec)/1E6;
+    _usec_accum += (Timestamp::now() - p->timestamp_anno()).to_double();
     _count++;
     return p;
 }
Index: elements/analysis/toipflowdumps.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/toipflowdumps.cc,v
retrieving revision 1.36
diff -u -u -w -r1.36 toipflowdumps.cc
--- elements/analysis/toipflowdumps.cc	16 Sep 2004 04:46:42 -0000	1.36
+++ elements/analysis/toipflowdumps.cc	30 Dec 2004 23:50:26 -0000
@@ -65,9 +65,9 @@
     _first_seq[0] = _first_seq[1] = 0;
 
     if (absolute_time)
-	_first_timestamp = make_timeval(0, 0);
+	_first_timestamp = Timestamp();
     else			// make first packet have timestamp .000001
-	_first_timestamp = p->timestamp_anno() - make_timeval(0, 1);
+	_first_timestamp = p->timestamp_anno() - Timestamp::epsilon();
 
     if (ip_id)
 	_ip_ids = new uint16_t[NPKT];
@@ -122,8 +122,12 @@
 	if (ni >= _nnote || _note[ni].before_pkt > pi) {
 	    int pos;
 
-	    buf.u[1] = ntohl(_pkt[pi].timestamp.tv_sec);
-	    buf.u[2] = ntohl(_pkt[pi].timestamp.tv_usec);
+	    buf.u[1] = ntohl(_pkt[pi].timestamp.sec());
+#if HAVE_NANOTIMESTAMP
+	    buf.u[2] = ntohl(_pkt[pi].timestamp.nsec());
+#else
+	    buf.u[2] = ntohl(_pkt[pi].timestamp.usec());
+#endif
 	    if (_ip_p == IP_PROTO_TCP) {
 		buf.u[3] = ntohl(_pkt[pi].th_seq);
 		buf.u[4] = ntohl(_pkt[pi].payload_len);
@@ -194,7 +198,11 @@
 	   << (_ip_p == IP_PROTO_TCP ? 'T' : 'U')
 	   << "\n!aggregate " << _aggregate << '\n';
 
+#if HAVE_NANOTIMESTAMP
+	sa << "!data ntimestamp";
+#else
 	sa << "!data timestamp";
+#endif
 	if (_binary) {
 	    if (_ip_p == IP_PROTO_TCP)
 		sa << " tcp_seq payload_len tcp_ack";
@@ -232,7 +240,7 @@
 	    sa << "!firstseq > " << _first_seq[0] << '\n';
 	if (_have_first_seq[1] && _first_seq[1] && _ip_p == IP_PROTO_TCP)
 	    sa << "!firstseq < " << _first_seq[1] << '\n';
-	if (timerisset(&_first_timestamp))
+	if (_first_timestamp)
 	    sa << "!firsttime " << _first_timestamp << '\n';
 	if (_binary)
 	    sa << "!binary\n";
Index: elements/analysis/toipflowdumps.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/toipflowdumps.hh,v
retrieving revision 1.21
diff -u -u -w -r1.21 toipflowdumps.hh
--- elements/analysis/toipflowdumps.hh	3 May 2004 06:04:20 -0000	1.21
+++ elements/analysis/toipflowdumps.hh	30 Dec 2004 23:50:26 -0000
@@ -170,7 +170,7 @@
     virtual void add_note(uint32_t, const String &, ErrorHandler * = 0);
 
     struct Pkt {
-	struct timeval timestamp;
+	Timestamp timestamp;
 	tcp_seq_t th_seq;
 	tcp_seq_t th_ack;
 	uint8_t direction;
@@ -218,7 +218,7 @@
 	int _tcp_opt;
 	int _npkt;
 	int _nnote;
-	struct timeval _first_timestamp;
+	Timestamp _first_timestamp;
 	bool _have_first_seq[2];
 	tcp_seq_t _first_seq[2];
 	Pkt _pkt[NPKT];
Index: elements/analysis/toipsumdump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/toipsumdump.cc,v
retrieving revision 1.56
diff -u -u -w -r1.56 toipsumdump.cc
--- elements/analysis/toipsumdump.cc	16 Sep 2004 07:10:19 -0000	1.56
+++ elements/analysis/toipsumdump.cc	30 Dec 2004 23:50:26 -0000
@@ -162,7 +162,8 @@
     // data description
     sa << "!data ";
     for (int i = 0; i < _fields.size(); i++)
-	sa << (i ? " " : "") << _fields[i]->name;
+	sa << (i ? " " : "")
+	   << (strcmp(_fields[i]->name, "ntimestamp") == 0 && !_binary ? "timestamp" : _fields[i]->name);
     sa << '\n';
 
     // binary marker
@@ -203,8 +204,7 @@
 	for (int i = 0; i < _fields.size(); i++) {
 	    if (i)
 		sa << ' ';
-	    if (_fields[i]->extract(d, _fields[i]->thunk)
-		&& _fields[i]->outa)
+	    if (_fields[i]->extract(d, _fields[i]->thunk) && _fields[i]->outa)
 		_fields[i]->outa(d, _fields[i]->thunk);
 	    else
 		sa << '-';
@@ -226,13 +226,13 @@
 	    total_len = count * len;
 
 	// do timestamp stepping
-	struct timeval end_timestamp = p->timestamp_anno();
-	struct timeval timestamp_delta;
-	if (timerisset(&FIRST_TIMESTAMP_ANNO(p))) {
+	Timestamp end_timestamp = p->timestamp_anno();
+	Timestamp timestamp_delta;
+	if (FIRST_TIMESTAMP_ANNO(p)) {
 	    timestamp_delta = (end_timestamp - FIRST_TIMESTAMP_ANNO(p)) / (count - 1);
 	    p->set_timestamp_anno(FIRST_TIMESTAMP_ANNO(p));
 	} else
-	    timestamp_delta = make_timeval(0, 0);
+	    timestamp_delta = Timestamp();
 	
 	SET_EXTRA_PACKETS_ANNO(p, 0);
 	for (uint32_t i = count; i > 0; i--) {
Index: elements/analysis/toipsumdump.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/analysis/toipsumdump.hh,v
retrieving revision 1.48
diff -u -u -w -r1.48 toipsumdump.hh
--- elements/analysis/toipsumdump.hh	17 Sep 2004 03:03:16 -0000	1.48
+++ elements/analysis/toipsumdump.hh	30 Dec 2004 23:50:26 -0000
@@ -36,7 +36,9 @@
 Space-separated list of field names. Each line of the summary dump will
 contain those fields. Valid field names, with examples, are:
 
-   timestamp    Packet timestamp: '996033261.451094'
+   timestamp    Packet timestamp: '996033261.451094' (either
+		microsecond or nanosecond precision, depending
+		on how Click was compiled)
    ts_sec       Seconds portion of timestamp: '996033261'
    ts_usec      Microseconds portion of timestamp: '451094'
    ts_usec1     Packet timestamp in microseconds
@@ -254,6 +256,8 @@
 
    Field Name    Length  Description
    timestamp        8    timestamp sec + usec
+   utimestamp	    8	 timestamp sec + usec
+   ntimestamp	    8	 timestamp sec + nsec
    ts_sec, ts_usec  4    timestamp sec/usec
    ts_usec1         8    timestamp in usec
    ip_src           4    source IP address
Index: elements/bsdmodule/anydevice.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/bsdmodule/anydevice.hh,v
retrieving revision 1.9
diff -u -u -w -r1.9 anydevice.hh
--- elements/bsdmodule/anydevice.hh	7 Dec 2004 20:24:32 -0000	1.9
+++ elements/bsdmodule/anydevice.hh	30 Dec 2004 23:50:26 -0000
@@ -21,7 +21,7 @@
 # define NETISR_CLICK 1		// must match empty slots in net/netisr.h !!!
 #endif
 
-#ifndef RR_SCHED
+#ifdef HAVE_STRIDE_SCHED
 # define CLICK_DEVICE_ADJUST_TICKETS 1
 #endif
 
Index: elements/etherswitch/bridgemessage.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/etherswitch/bridgemessage.cc,v
retrieving revision 1.19
diff -u -u -w -r1.19 bridgemessage.cc
--- elements/etherswitch/bridgemessage.cc	6 Aug 2002 00:51:27 -0000	1.19
+++ elements/etherswitch/bridgemessage.cc	30 Dec 2004 23:50:27 -0000
@@ -76,7 +76,7 @@
 BridgeMessage::reset(uint64_t bridge_id) {
   _root = _bridge_id = bridge_id;
   _cost = 0;
-  _timestamp.tv_sec = ~(1 << 31); // Never expire
+  _timestamp._sec = ~(1 << 31); // Never expire
   _tc = false;
   _max_age = 20;
   _hello_time = 2;
@@ -85,8 +85,8 @@
 
 /* If message's timestamp is older than cutoff, make the message as
    bad as possible. */
-bool BridgeMessage::expire(const timeval* cutoff) {
-  if (timercmp(&_timestamp, cutoff, >))
+bool BridgeMessage::expire(const Timestamp& cutoff) {
+  if (_timestamp > cutoff)
     return false;
   expire();
   return true;
@@ -97,7 +97,7 @@
 void BridgeMessage::expire() {
   _root = _bridge_id = ~(uint64_t)0; // Worst possible
   _cost = ~(uint16_t)0;	// Worst possible
-  _timestamp.tv_sec = ~(1 << 31); // Never expire
+  _timestamp._sec = ~(1 << 31); // Never expire
   _tc = false;
 }
 
@@ -108,18 +108,11 @@
   _bridge_id = ntohq(msg->bridge_id);
   _port_id = ntohs(msg->port_id);
 
-  click_gettimeofday(&_timestamp);
+  _timestamp = Timestamp::now();
 
   // How stale is this message?
-  const int million = 1000000;
-  int lateness = (ntohs(msg->message_age) * million)/256;
-  _timestamp.tv_sec -= lateness / million;
-  _timestamp.tv_usec -= lateness % million;
-  if (_timestamp.tv_usec < 0) {
-    _timestamp.tv_sec--;
-    _timestamp.tv_usec += million;
-  }
-
+  int lateness = (ntohs(msg->message_age) * 1000000)/256;
+  _timestamp -= Timestamp::make_usec(lateness);
   _tc = msg->tc;
 
   // Propagate Parameters
@@ -142,16 +135,12 @@
   msg->bridge_id = htonq(_bridge_id);
   msg->port_id = htons(_port_id);
   // How stale is this message?
-  const int million = 1000000;
-  if (_timestamp.tv_sec == ~(1<<31)) { // Special "do not expire" value
+  if (_timestamp._sec == ~(1<<31)) { // Special "do not expire" value
     msg->message_age = htons(0);
   } else {
-    timeval t;
-    click_gettimeofday(&t);
-    t.tv_sec -= _timestamp.tv_sec;
-    t.tv_usec -= _timestamp.tv_usec;
-    msg->message_age = htons((t.tv_usec * 256)/million);
-    msg->message_age += htons(t.tv_sec * 256);
+    Timestamp t = Timestamp::now() - _timestamp;
+    msg->message_age = htons((t.usec() * 256)/1000000);
+    msg->message_age += htons(t.sec() * 256);
   }
 
   // Propagate Parameters
Index: elements/etherswitch/bridgemessage.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/etherswitch/bridgemessage.hh,v
retrieving revision 1.10
diff -u -u -w -r1.10 bridgemessage.hh
--- elements/etherswitch/bridgemessage.hh	6 Aug 2002 00:51:27 -0000	1.10
+++ elements/etherswitch/bridgemessage.hh	30 Dec 2004 23:50:27 -0000
@@ -3,6 +3,7 @@
 #include <click/glue.hh>
 #include <click/string.hh>
 #include <click/integers.hh>
+#include <click/timestamp.hh>
 CLICK_DECLS
 
 class BridgeMessage {
@@ -19,7 +20,7 @@
   static void fill_tcm(wire* msg);
 
   
-  bool expire(const timeval* cutoff);	// Possibly expire, based on timestamp
+  bool expire(const Timestamp& cutoff);	// Possibly expire, based on timestamp
   void expire();		// Set fields to worst values
 
 
@@ -79,7 +80,7 @@
 
   bool _tc;
 
-  timeval _timestamp; // When the message should be considered to have
+  Timestamp _timestamp; // When the message should be considered to have
 		      // been created, used for expiration.
 
   static void prep_msg(wire* msg);
Index: elements/etherswitch/spantree.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/etherswitch/spantree.cc,v
retrieving revision 1.32
diff -u -u -w -r1.32 spantree.cc
--- elements/etherswitch/spantree.cc	3 May 2004 06:04:21 -0000	1.32
+++ elements/etherswitch/spantree.cc	30 Dec 2004 23:50:27 -0000
@@ -106,15 +106,12 @@
 void
 EtherSpanTree::periodic() {
   // Push LISTEN and LEARN ports forward.
-  timeval now;
-  timeval cutoff;
-  click_gettimeofday(&now);
-  cutoff = now;
-  cutoff.tv_sec -= _best._forward_delay;
+    Timestamp cutoff = Timestamp::now();
+    cutoff._sec -= _best._forward_delay;
 
   for (int i = 0; i < _port.size(); i++) {
     if (_port[i].state == LISTEN || _port[i].state == LEARN)
-      if (timercmp(&_port[i].since, &cutoff, <)) {
+	    if (_port[i].since < cutoff) {
 	set_state(i, FORWARD);
       }
   }
@@ -125,13 +122,12 @@
 
 bool
 EtherSpanTree::expire() {
-  timeval t;
-  click_gettimeofday(&t);
-  t.tv_sec -= _best._max_age;
+    Timestamp t = Timestamp::now();
+    t._sec -= _best._max_age;
 
   bool expired = false;
   for (int i = 0; i < _port.size(); i++) {
-    if (_port[i].msg.expire(&t)) {
+	if (_port[i].msg.expire(t)) {
       expired = true;
       click_chatter("Expiring message on port %d", i);
     }
@@ -206,7 +202,7 @@
   click_chatter("Changing port %d from %d to %d", i, _port[i].state, state);
 
   _port[i].state = state;
-  click_gettimeofday(&_port[i].since);
+  _port[i].since = Timestamp::now();
 
 
   switch (state) {
@@ -294,10 +290,9 @@
     msg->bridge_id = htonq(((uint64_t)_bridge_priority << 48) | _bridge_id);
     msg->port_id = htons(output);
     if (_topology_change) {
-      timeval cutoff;
-      click_gettimeofday(&cutoff);
-      cutoff.tv_sec -= _best._forward_delay + _best._max_age;
-      if (timercmp(_topology_change, &cutoff, <)) {
+      Timestamp cutoff = Timestamp::now();
+      cutoff._sec -= _best._forward_delay + _best._max_age;
+      if (*_topology_change < cutoff) {
 	delete _topology_change;
 	_topology_change = 0;
       } else {
Index: elements/etherswitch/spantree.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/etherswitch/spantree.hh,v
retrieving revision 1.17
diff -u -u -w -r1.17 spantree.hh
--- elements/etherswitch/spantree.hh	3 May 2004 06:04:21 -0000	1.17
+++ elements/etherswitch/spantree.hh	30 Dec 2004 23:50:27 -0000
@@ -38,7 +38,7 @@
   Suppressor* _input_sup;
   Suppressor* _output_sup;
   EtherSwitch* _switch;
-  timeval* _topology_change;	// If set, tc should be sent with messages.
+  Timestamp* _topology_change;	// If set, tc should be sent with messages.
   bool _send_tc_msg;		// If true, tcm should be sent to root port.
   
   uint64_t _bridge_id;		// Should be 48 bits
@@ -55,7 +55,7 @@
   enum PortState {BLOCK, LISTEN, LEARN, FORWARD};
   struct PortInfo {
     PortState state;
-    timeval since;		// When the port entered the state
+    Timestamp since;		// When the port entered the state
     bool needs_tca;
     BridgeMessage msg;
     PortInfo() { state = BLOCK; needs_tca = false; }
Index: elements/grid/ackretrysender.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/ackretrysender.hh,v
retrieving revision 1.5
diff -u -u -w -r1.5 ackretrysender.hh
--- elements/grid/ackretrysender.hh	3 May 2004 06:04:21 -0000	1.5
+++ elements/grid/ackretrysender.hh	30 Dec 2004 23:50:27 -0000
@@ -91,9 +91,9 @@
   unsigned int _history_length;
 
   struct tx_result_t {
-    tx_result_t(const struct timeval &t, unsigned n, bool s) 
+    tx_result_t(const Timestamp &t, unsigned n, bool s) 
       : pkt_time(t), num_tx(n), success(s) { }
-    struct timeval pkt_time;
+    Timestamp pkt_time;
     unsigned num_tx;
     bool success;
   };
Index: elements/grid/ackretrysender2.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/ackretrysender2.cc,v
retrieving revision 1.4
diff -u -u -w -r1.4 ackretrysender2.cc
--- elements/grid/ackretrysender2.cc	25 Feb 2004 18:11:32 -0000	1.4
+++ elements/grid/ackretrysender2.cc	30 Dec 2004 23:50:27 -0000
@@ -251,7 +251,7 @@
 }
 
 void
-ACKRetrySender2::add_stat(const struct timeval &t, unsigned num_tx, bool succ) 
+ACKRetrySender2::add_stat(const Timestamp &t, unsigned num_tx, bool succ) 
 {
   _history.push_back(tx_result_t(t, num_tx, succ));
   while (_history.size() > (int) _history_length)
Index: elements/grid/ackretrysender2.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/ackretrysender2.hh,v
retrieving revision 1.4
diff -u -u -w -r1.4 ackretrysender2.hh
--- elements/grid/ackretrysender2.hh	3 May 2004 06:04:21 -0000	1.4
+++ elements/grid/ackretrysender2.hh	30 Dec 2004 23:50:27 -0000
@@ -121,9 +121,9 @@
   unsigned int _history_length;
 
   struct tx_result_t {
-    tx_result_t(const struct timeval &t, unsigned n, bool s) 
+    tx_result_t(const Timestamp &t, unsigned n, bool s) 
       : pkt_time(t), num_tx(n), success(s) { }
-    struct timeval pkt_time;
+    Timestamp pkt_time;
     unsigned num_tx;
     bool success;
   };
@@ -146,7 +146,7 @@
 
   void check();
 
-  void add_stat(const struct timeval &t, unsigned num_tx, bool succ);
+  void add_stat(const Timestamp &t, unsigned num_tx, bool succ);
 
   static String print_history(Element *e, void *);
   static String print_summary(Element *e, void *);
Index: elements/grid/dsdvroutetable.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/dsdvroutetable.cc,v
retrieving revision 1.76
diff -u -u -w -r1.76 dsdvroutetable.cc
--- elements/grid/dsdvroutetable.cc	24 Jun 2004 00:03:57 -0000	1.76
+++ elements/grid/dsdvroutetable.cc	30 Dec 2004 23:50:27 -0000
@@ -421,9 +421,7 @@
   dsdv_assert(old && *old && !(*old)->scheduled() && oldhp && *oldhp);
 
   if (_log) {
-    timeval tv;
-    click_gettimeofday(&tv);
-    _log->log_start_expire_handler(tv);
+    _log->log_start_expire_handler(Timestamp::now());
     _log->log_expired_route(GridGenericLogger::TIMEOUT, ip);
   }
 
@@ -1026,11 +1024,8 @@
 
   grid_hello *hlo = (grid_hello *) (gh + 1);
    
-  if (_log) {
-    struct timeval tv;
-    click_gettimeofday(&tv);
-    _log->log_start_recv_advertisement(ntohl(hlo->seq_no), ipaddr, tv);
-  }
+  if (_log)
+    _log->log_start_recv_advertisement(ntohl(hlo->seq_no), ipaddr, Timestamp::now());
   
   // assume CheckGridHeader was used to check for truncated packets
   // and bad checksums.  Sanity check number of entries.
@@ -1511,9 +1506,7 @@
   memset(p->data(), 0, p->length());
 
   /* fill in the timestamp */
-  struct timeval tv;
-  click_gettimeofday(&tv);
-  p->set_timestamp_anno(tv);
+  p->set_timestamp_anno(Timestamp::now());
 
   /* fill in ethernet header */
   click_ether *eh = (click_ether *) p->data();
@@ -1537,7 +1530,7 @@
   hlo->is_gateway = _gw_info ? _gw_info->is_gateway() : false;
 
   if (_log)
-    _log->log_sent_advertisement(_seq_no, tv);
+    _log->log_sent_advertisement(_seq_no, p->timestamp_anno());
   
   _bcast_count++;
   grid_hdr::set_pad_bytes(*gh, htonl(_bcast_count));
@@ -1584,11 +1577,9 @@
 DSDVRouteTable::log_dump_hook(bool reschedule)
 {
   if (_log) {
-    struct timeval tv;
-    click_gettimeofday(&tv);
     Vector<RouteEntry> vec;
     get_all_entries(vec);
-    _log->log_route_dump(vec, tv);
+    _log->log_route_dump(vec, Timestamp::now());
   }
   if (reschedule)
     _log_dump_timer.schedule_after_ms(_log_dump_period); 
Index: elements/grid/floodinglocquerier.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/floodinglocquerier.cc,v
retrieving revision 1.41
diff -u -u -w -r1.41 floodinglocquerier.cc
--- elements/grid/floodinglocquerier.cc	24 Jun 2004 00:03:57 -0000	1.41
+++ elements/grid/floodinglocquerier.cc	30 Dec 2004 23:50:27 -0000
@@ -120,9 +120,7 @@
   ASSERT_ALIGNED(q->data());
   q->pull(2);
 
-  struct timeval tv;
-  click_gettimeofday(&tv);
-  q->set_timestamp_anno(tv);
+  q->set_timestamp_anno(Timestamp::now());
 
   memset(q->data(), '\0', q->length());
   e = (click_ether *) q->data();
Index: elements/grid/gridgenericlogger.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/gridgenericlogger.hh,v
retrieving revision 1.2
diff -u -u -w -r1.2 gridgenericlogger.hh
--- elements/grid/gridgenericlogger.hh	1 Feb 2003 05:16:22 -0000	1.2
+++ elements/grid/gridgenericlogger.hh	30 Dec 2004 23:50:27 -0000
@@ -30,21 +30,21 @@
   };
 
 
-  virtual void log_sent_advertisement(unsigned seq_no, struct timeval when) = 0;
-  virtual void log_start_recv_advertisement(unsigned seq_no, unsigned ip, struct timeval when) = 0;
+  virtual void log_sent_advertisement(unsigned seq_no, const Timestamp &when) = 0;
+  virtual void log_start_recv_advertisement(unsigned seq_no, unsigned ip, const Timestamp &when) = 0;
   virtual void log_added_route(reason_t why, const GridGenericRouteTable::RouteEntry &r) = 0;
   virtual void log_added_route(reason_t why, const GridGenericRouteTable::RouteEntry &r, 
 			       const unsigned extra) = 0;
   virtual void log_expired_route(reason_t why, unsigned ip) = 0;
   virtual void log_triggered_route(unsigned ip) = 0;
   virtual void log_end_recv_advertisement() = 0;
-  virtual void log_start_expire_handler(struct timeval when) = 0;
+  virtual void log_start_expire_handler(const Timestamp &when) = 0;
   virtual void log_end_expire_handler() = 0;
-  virtual void log_route_dump(const Vector<GridGenericRouteTable::RouteEntry> &rt, struct timeval when) = 0;
+  virtual void log_route_dump(const Vector<GridGenericRouteTable::RouteEntry> &rt, const Timestamp &when) = 0;
   
   // assumes Grid packet
-  virtual void log_tx_err(const Packet *p, int err, struct timeval when) = 0;
-  virtual void log_no_route(const Packet *p, struct timeval when) = 0;
+  virtual void log_tx_err(const Packet *p, int err, const Timestamp &when) = 0;
+  virtual void log_no_route(const Packet *p, const Timestamp &when) = 0;
 
   virtual ~GridGenericLogger() { }
 };
Index: elements/grid/gridlogger.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/gridlogger.hh,v
retrieving revision 1.22
diff -u -u -w -r1.22 gridlogger.hh
--- elements/grid/gridlogger.hh	3 May 2004 06:04:21 -0000	1.22
+++ elements/grid/gridlogger.hh	30 Dec 2004 23:50:27 -0000
@@ -217,25 +217,25 @@
 
 public:
 
-  void log_sent_advertisement(unsigned seq_no, struct timeval when) { 
+  void log_sent_advertisement(unsigned seq_no, const Timestamp &when) { 
     if (!check_state(WAITING)) 
       return;
     if (!check_space(1 + sizeof(seq_no) + sizeof(when)))
       return;
     add_one_byte(SENT_AD_CODE);
     add_long(seq_no);
-    add_timeval(when);
+    add_timeval(when.to_timeval());
     write_buf();
   }
 
-  void log_start_recv_advertisement(unsigned seq_no, unsigned ip, struct timeval when) {
+  void log_start_recv_advertisement(unsigned seq_no, unsigned ip, const Timestamp &when) {
     if (!check_state(WAITING)) 
       return;
     _state = RECV_AD;
     add_one_byte(BEGIN_RECV_CODE);
     add_ip(ip);
     add_long(seq_no);
-    add_timeval(when);
+    add_timeval(when.to_timeval());
   }
   
   void log_added_route(reason_t why, const GridGenericRouteTable::RouteEntry &r) {
@@ -291,12 +291,12 @@
     write_buf();
   }
 
-  void log_start_expire_handler(struct timeval when) {
+  void log_start_expire_handler(const Timestamp &when) {
     if (!check_state(WAITING)) 
       return;
     _state = EXPIRE_HANDLER;
     add_one_byte(BEGIN_EXPIRE_CODE);
-    add_timeval(when);
+    add_timeval(when.to_timeval());
   }
 
   void log_end_expire_handler() {
@@ -310,11 +310,11 @@
       write_buf();
   }
 
-  void log_route_dump(const Vector<GridGenericRouteTable::RouteEntry> &rt, struct timeval when) {
+  void log_route_dump(const Vector<GridGenericRouteTable::RouteEntry> &rt, const Timestamp &when) {
     if (!check_state(WAITING))
       return;
     add_one_byte(ROUTE_DUMP_CODE);
-    add_timeval(when);
+    add_timeval(when.to_timeval());
     int n = rt.size();
     add_long(n);
     for (int i = 0; i < rt.size(); i++) {
@@ -328,27 +328,27 @@
   }
 
   // assumes Grid packet
-  void log_tx_err(const Packet *p, int err, struct timeval when) {
+  void log_tx_err(const Packet *p, int err, const Timestamp &when) {
     if (!check_state(WAITING)) 
       return;
     struct click_ether *eh = (click_ether *) (p->data());
      if (eh->ether_type != htons(ETHERTYPE_GRID)) 
       return;
     add_one_byte(TX_ERR_CODE);
-    add_timeval(when);
+    add_timeval(when.to_timeval());
     add_long((unsigned long) err);
     log_pkt(eh);
     write_buf();
   }
 
-  void log_no_route(const Packet *p, struct timeval when) {
+  void log_no_route(const Packet *p, const Timestamp &when) {
     if (!check_state(WAITING))
       return;
     struct click_ether *eh = (click_ether *) (p->data());
     if (eh->ether_type != htons(ETHERTYPE_GRID)) 
       return;
     add_one_byte(NO_ROUTE_CODE);
-    add_timeval(when);
+    add_timeval(when.to_timeval());
     log_pkt(eh);
     write_buf();
   }
Index: elements/grid/gridprobehandler.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/gridprobehandler.cc,v
retrieving revision 1.16
diff -u -u -w -r1.16 gridprobehandler.cc
--- elements/grid/gridprobehandler.cc	24 Jun 2004 00:03:57 -0000	1.16
+++ elements/grid/gridprobehandler.cc	30 Dec 2004 23:50:27 -0000
@@ -122,10 +122,7 @@
   WritablePacket *q = Packet::make(sizeof(*e) + sizeof(*gh2) + sizeof(*nb2) + sizeof(*rr) + 2);
   q->pull(2);
   
-  struct timeval tv;
-  int res = gettimeofday(&tv, 0);
-  if (res == 0) 
-    q->set_timestamp_anno(tv);
+  q->set_timestamp_anno(Timestamp::now());
 
   memset(q->data(), 0, q->length());
   e = (click_ether *) q->data();
Index: elements/grid/gridprobereplyreceiver.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/gridprobereplyreceiver.cc,v
retrieving revision 1.14
diff -u -u -w -r1.14 gridprobereplyreceiver.cc
--- elements/grid/gridprobereplyreceiver.cc	24 Jun 2004 00:03:57 -0000	1.14
+++ elements/grid/gridprobereplyreceiver.cc	30 Dec 2004 23:50:27 -0000
@@ -80,7 +80,7 @@
   tx_time.tv_sec = ntohl(tx_time.tv_sec);
   tx_time.tv_usec = ntohl(tx_time.tv_usec);
 
-  struct timeval rtt = p->timestamp_anno() - tx_time;
+  struct timeval rtt = p->timestamp_anno().to_timeval() - tx_time;
 
   char buf[200];
   snprintf(buf, sizeof(buf),
Index: elements/grid/gridprobesender.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/gridprobesender.cc,v
retrieving revision 1.11
diff -u -u -w -r1.11 gridprobesender.cc
--- elements/grid/gridprobesender.cc	24 Jun 2004 00:03:57 -0000	1.11
+++ elements/grid/gridprobesender.cc	30 Dec 2004 23:50:27 -0000
@@ -63,10 +63,7 @@
   WritablePacket *q = Packet::make(sizeof(*e) + sizeof(*gh) + sizeof(*nb) + sizeof(*rp) + 2);
   q->pull(2);
   
-  struct timeval tv;
-  int res = gettimeofday(&tv, 0);
-  if (res == 0) 
-    q->set_timestamp_anno(tv);
+  q->set_timestamp_anno(Timestamp::now());
 
   memset(q->data(), 0, q->length());
   e = (click_ether *) q->data();
@@ -89,8 +86,8 @@
   nb->hops_travelled = 0;
 
   rp->nonce = htonl(nonce);
-  rp->send_time.tv_sec = htonl(tv.tv_sec);
-  rp->send_time.tv_usec = htonl(tv.tv_usec);
+  rp->send_time.tv_sec = htonl(q->timestamp_anno().sec());
+  rp->send_time.tv_usec = htonl(q->timestamp_anno().usec());
   
   output(0).push(q);
 }
Index: elements/grid/gridroutetable.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/gridroutetable.cc,v
retrieving revision 1.71
diff -u -u -w -r1.71 gridroutetable.cc
--- elements/grid/gridroutetable.cc	24 Jun 2004 00:03:57 -0000	1.71
+++ elements/grid/gridroutetable.cc	30 Dec 2004 23:50:28 -0000
@@ -697,11 +697,10 @@
   grid_hello *hlo = (grid_hello *) (gh + 1);
    
   // extended logging
-  timeval tv;
-  gettimeofday(&tv, 0);
-  _extended_logging_errh->message("recvd %u from %s %ld %ld", ntohl(hlo->seq_no), ipaddr.s().cc(), tv.tv_sec, tv.tv_usec);
+  Timestamp ts = Timestamp::now();
+  _extended_logging_errh->message("recvd %u from %s %d %d", ntohl(hlo->seq_no), ipaddr.s().cc(), ts.sec(), ts.usec());
   if (_log)
-    _log->log_start_recv_advertisement(ntohl(hlo->seq_no), ipaddr, tv);
+    _log->log_start_recv_advertisement(ntohl(hlo->seq_no), ipaddr, ts);
   
   if (_frozen) {
     if (_log)
@@ -1303,11 +1302,9 @@
   if (_dump_tick == 50) {
     _dump_tick = 0;
     if (_log) {
-      struct timeval tv;
-      gettimeofday(&tv, 0);
       Vector<RouteEntry> vec;
       get_all_entries(vec);
-      _log->log_route_dump(vec, tv);
+      _log->log_route_dump(vec, Timestamp::now());
     }
   }
       
@@ -1324,11 +1321,9 @@
   xip_t expired_rtes;
   xip_t expired_next_hops;
 
-  timeval tv;
-  gettimeofday(&tv, 0);
-
+  Timestamp ts = Timestamp::now();
   if (_log)
-    _log->log_start_expire_handler(tv);
+    _log->log_start_expire_handler(ts);
 
   bool table_changed = false;
 
@@ -1341,7 +1336,7 @@
 	decr_ttl(i.value().ttl, jiff_to_msec(jiff - i.value().last_updated_jiffies)) == 0) {
       expired_rtes.insert(i.value().dest_ip, true);
 
-      _extended_logging_errh->message ("expiring %s %ld %ld", i.value().dest_ip.s().cc(), tv.tv_sec, tv.tv_usec);  // extended logging
+      _extended_logging_errh->message ("expiring %s %d %d", i.value().dest_ip.s().cc(), ts.sec(), ts.usec());  // extended logging
       table_changed = true;
 
       if (_log)
@@ -1365,7 +1360,7 @@
 	!expired_rtes.findp(i.value().dest_ip)) {
       expired_rtes.insert(i.value().dest_ip, true);
 
-      _extended_logging_errh->message("next to %s expired %ld %ld", i.value().dest_ip.s().cc(), tv.tv_sec, tv.tv_usec);  // extended logging
+      _extended_logging_errh->message("next to %s expired %d %d", i.value().dest_ip.s().cc(), ts.sec(), ts.usec());  // extended logging
       
       if (_log)
 	_log->log_expired_route(GridLogger::NEXT_HOP_EXPIRED, i.value().dest_ip);
@@ -1488,10 +1483,7 @@
   memset(p->data(), 0, p->length());
 
   /* fill in the timestamp */
-  struct timeval tv;
-  int res = gettimeofday(&tv, 0);
-  if (res == 0) 
-    p->set_timestamp_anno(tv);
+  p->set_timestamp_anno(Timestamp::now());
 
   /* fill in ethernet header */
   click_ether *eh = (click_ether *) p->data();
@@ -1515,10 +1507,10 @@
   hlo->is_gateway = _gw_info->is_gateway ();
 
   /* extended logging */
-  gettimeofday(&tv, 0);
-  _extended_logging_errh->message("sending %u %ld %ld", _seq_no, tv.tv_sec, tv.tv_usec);
+  Timestamp now = Timestamp::now();
+  _extended_logging_errh->message("sending %u %ld %ld", _seq_no, now.sec(), now.usec());
   if (_log)
-    _log->log_sent_advertisement(_seq_no, tv);
+    _log->log_sent_advertisement(_seq_no, now);
 
   /* 
    * Update the sequence number for periodic updates, but not for
Index: elements/grid/gridtxerror.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/gridtxerror.cc,v
retrieving revision 1.7
diff -u -u -w -r1.7 gridtxerror.cc
--- elements/grid/gridtxerror.cc	24 Jun 2004 00:03:57 -0000	1.7
+++ elements/grid/gridtxerror.cc	30 Dec 2004 23:50:28 -0000
@@ -58,12 +58,8 @@
 GridTxError::push(int, Packet *p) 
 {
   /* log the error */
-  int err = SEND_ERR_ANNO(p);
-  struct timeval tv;
-  click_gettimeofday(&tv);
-
   if (_log)
-    _log->log_tx_err(p, err, tv);
+    _log->log_tx_err(p, SEND_ERR_ANNO(p), Timestamp::now());
 
   p->kill();
 }
Index: elements/grid/hello.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/hello.cc,v
retrieving revision 1.44
diff -u -u -w -r1.44 hello.cc
--- elements/grid/hello.cc	24 Jun 2004 00:03:57 -0000	1.44
+++ elements/grid/hello.cc	30 Dec 2004 23:50:28 -0000
@@ -94,10 +94,7 @@
   p->pull(2);
   memset(p->data(), 0, p->length());
 
-  struct timeval tv;
-  int res = gettimeofday(&tv, 0);
-  if (res == 0) 
-    p->set_timestamp_anno(tv);
+  p->set_timestamp_anno(Timestamp::now());
 
   click_ether *eh = (click_ether *) p->data();
   memset(eh->ether_dhost, 0xff, 6); // broadcast
Index: elements/grid/linkstat.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/linkstat.cc,v
retrieving revision 1.31
diff -u -u -w -r1.31 linkstat.cc
--- elements/grid/linkstat.cc	24 Jun 2004 00:03:57 -0000	1.31
+++ elements/grid/linkstat.cc	30 Dec 2004 23:50:28 -0000
@@ -83,9 +83,7 @@
   p->pull(2);
   memset(p->data(), 0, p->length());
 
-  struct timeval tv;
-  click_gettimeofday(&tv);
-  p->set_timestamp_anno(tv);
+  p->set_timestamp_anno(Timestamp::now());
   
   // fill in ethernet header 
   click_ether *eh = (click_ether *) p->data();
@@ -129,10 +127,7 @@
   unsigned max_jitter = _period / 10;
   long r2 = random();
   unsigned j = (unsigned) ((r2 >> 1) % (max_jitter + 1));
-  unsigned int delta_us = 1000 * ((r2 & 1) ? _period - j : _period + j);
-  _next_bcast.tv_usec += delta_us;
-  _next_bcast.tv_sec +=  _next_bcast.tv_usec / 1000000;
-  _next_bcast.tv_usec = (_next_bcast.tv_usec % 1000000);
+  _next_bcast += Timestamp::make_usec(1000 * ((r2 & 1) ? _period - j : _period + j));
   _send_timer->schedule_at(_next_bcast);
 
   checked_output_push(0, p);
@@ -177,8 +172,7 @@
       return errh->error("Source Ethernet address must be specified to send probes");
     _send_timer = new Timer(static_send_hook, this);
     _send_timer->initialize(this);
-    click_gettimeofday(&_next_bcast);
-    _next_bcast.tv_sec++;
+    _next_bcast = Timestamp::now() + Timestamp(1, 0);
     _send_timer->schedule_at(_next_bcast);
   }
   return 0;
Index: elements/grid/linkstat.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/linkstat.hh,v
retrieving revision 1.18
diff -u -u -w -r1.18 linkstat.hh
--- elements/grid/linkstat.hh	3 May 2004 06:04:22 -0000	1.18
+++ elements/grid/linkstat.hh	30 Dec 2004 23:50:28 -0000
@@ -207,7 +207,7 @@
   void send_hook();
 
   Timer *_send_timer;
-  struct timeval _next_bcast;
+  Timestamp _next_bcast;
 
   bool _use_proto2;
 
Index: elements/grid/linktester.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/linktester.cc,v
retrieving revision 1.2
diff -u -u -w -r1.2 linktester.cc
--- elements/grid/linktester.cc	12 Jan 2004 22:12:10 -0000	1.2
+++ elements/grid/linktester.cc	30 Dec 2004 23:50:28 -0000
@@ -110,21 +110,19 @@
   if (!res)
     return errh->error("Unable to initialize random number generator");
 
-  struct timeval tv;
-  click_gettimeofday(&tv);
+  Timestamp now = Timestamp::now();
 
   if (_start_time < 0) // start ``immediately''
-    _start_time = tv.tv_sec + 5;
+    _start_time = now.sec() + 5;
 
-  if (tv.tv_sec >= (int) _start_time)
+  if (now.sec() >= (int) _start_time)
     return errh->error("Start time %u has alread passed", _start_time);
 
   _timer.initialize(this);
-  _start_time_tv.tv_sec = _start_time;
-  _start_time_tv.tv_usec = 0;
+  _start_time_tv = Timestamp(_start_time, 0);
   _timer.schedule_at(_start_time_tv);
 
-  _last_time = tv;
+  _last_time = now;
   _next_time = _start_time_tv;
 
   return 0;
@@ -133,11 +131,10 @@
 void
 LinkTester::timer_hook()
 {
-  struct timeval tv;
-  click_gettimeofday(&tv);
+  Timestamp tv = Timestamp::now();
 #if 1
-  click_chatter("OK %s    (delta: %s)\n", timeval_to_str(tv).cc(),
-		timeval_to_str(tv - _last_time).cc());
+  click_chatter("OK %{timestamp}    (delta: %s)\n", tv.unparse().cc(),
+		(tv - _last_time).unparse().cc());
 #endif
   _last_time = tv;
   switch (_curr_state) {
@@ -153,7 +150,7 @@
 }
 
 void 
-LinkTester::handle_timer_waiting(const struct timeval &tv)
+LinkTester::handle_timer_waiting(const Timestamp &tv)
 {
   assert(_curr_state == WAITING_TO_START);
   _iterations_done = 0;
@@ -171,8 +168,7 @@
   else {
     _curr_state = LISTENING;
     int listen_for = calc_listen_time() + calc_pad_time();
-    _next_time.tv_sec = _start_time + (listen_for / 1000);
-    _next_time.tv_usec = 1000 * (listen_for % 1000);
+    _next_time = _start_time_tv + Timestamp::make_msec(listen_for);
     
     assert(_next_time > tv);
     _timer.schedule_at(_next_time);
@@ -180,7 +176,7 @@
 }
 
 void 
-LinkTester::handle_timer_listening(const struct timeval &tv)
+LinkTester::handle_timer_listening(const Timestamp &tv)
 {
   assert(_curr_state == LISTENING);
 
@@ -199,7 +195,7 @@
 }
 
 void 
-LinkTester::handle_timer_bcast(const struct timeval &tv)
+LinkTester::handle_timer_bcast(const Timestamp &tv)
 {
   assert(_curr_state == BCAST_1 || _curr_state == BCAST_2);
   send_broadcast_packet((unsigned short) _bcast_packet_size, tv, 
@@ -209,7 +205,7 @@
 
   // when would we like to send the next bcast packet?
   unsigned int delta = draw_random_msecs(_bcast_lambda);
-  struct timeval new_next_time = _next_time + msecs_to_timeval(delta);
+  Timestamp new_next_time = _next_time + Timestamp::make_msec(delta);
   
   // is there enough time left to send the next packet?
   if (new_next_time <= last_bcast_time(_iterations_done,
@@ -254,14 +250,14 @@
 }
  
 void 
-LinkTester::handle_timer_unicast(const struct timeval &tv)
+LinkTester::handle_timer_unicast(const Timestamp &tv)
 {
   assert(_curr_state == UNICAST);
   send_unicast_packet(tv, _packets_sent, _iterations_done);
   _packets_sent++;
 
   unsigned int delta = draw_random_msecs(_lambda);
-  struct timeval new_next_time = _next_time + msecs_to_timeval(delta);
+  Timestamp new_next_time = _next_time + Timestamp::make_msec(delta);
 
   // is there enough time left to sent the next packet?
   if (new_next_time <= last_unicast_time(_iterations_done))
@@ -296,7 +292,7 @@
   return _bcast_send_time;
 }
 
-struct timeval
+Timestamp
 LinkTester::first_unicast_time(unsigned int iter)
 {
   unsigned int iter_time = 2 * (calc_listen_time() + calc_pad_time());
@@ -304,10 +300,10 @@
   delta += calc_bcast_time() + calc_pad_time();
   if (!_send_first) // let other node send first
     delta += calc_listen_time() + calc_pad_time();
-  return msecs_to_timeval(delta) + _start_time_tv;
+  return Timestamp::make_msec(delta) + _start_time_tv;
 }
 
-struct timeval
+Timestamp
 LinkTester::first_bcast_time(unsigned int iter, bool before)
 {
   unsigned int iter_time = 2 * (calc_listen_time() + calc_pad_time());
@@ -316,23 +312,23 @@
     delta += calc_listen_time() + calc_pad_time();
   if (!before)
     delta += calc_bcast_time() + calc_pad_time() + calc_unicast_time() + calc_pad_time();
-  return msecs_to_timeval(delta) + _start_time_tv;
+  return Timestamp::make_msec(delta) + _start_time_tv;
 }
 
-struct timeval
+Timestamp
 LinkTester::last_unicast_time(unsigned int iter)
 {
-  return first_unicast_time(iter) + msecs_to_timeval(calc_unicast_time());
+  return first_unicast_time(iter) + Timestamp::make_msec(calc_unicast_time());
 }
 
-struct timeval
+Timestamp
 LinkTester::last_bcast_time(unsigned int iter, bool before)
 {
-  return first_bcast_time(iter, before) + msecs_to_timeval(calc_bcast_time());
+  return first_bcast_time(iter, before) + Timestamp::make_msec(calc_bcast_time());
 }
 
 void
-LinkTester::send_unicast_packet(const struct timeval &tv,
+LinkTester::send_unicast_packet(const Timestamp &tv,
 				unsigned int seq, unsigned int iter)
 {
   WritablePacket *p = Packet::make(_packet_size);
@@ -347,8 +343,8 @@
   payload->size = htons(_packet_size);
   payload->iteration = htonl(iter);
   payload->seq_no = htonl(seq);
-  payload->tx_sec = htonl(tv.tv_sec);
-  payload->tx_usec = htonl(tv.tv_usec);
+  payload->tx_sec = htonl(tv.sec());
+  payload->tx_usec = htonl(tv.usec());
 
   unsigned int data_sz = _packet_size - sizeof(click_ether) - sizeof(payload_t);
   if (data_sz > 0)
@@ -358,7 +354,7 @@
 }
 
 void
-LinkTester::send_broadcast_packet(unsigned short psz, const struct timeval &tv,
+LinkTester::send_broadcast_packet(unsigned short psz, const Timestamp &tv,
 				  bool before, unsigned int seq, unsigned int iter)
 {
   assert(psz >= sizeof(click_ether) + sizeof(payload_t));
@@ -376,8 +372,8 @@
   payload->before = before ? 1 : 0;
   payload->iteration = htonl(iter);
   payload->seq_no = htonl(seq);
-  payload->tx_sec = htonl(tv.tv_sec);
-  payload->tx_usec = htonl(tv.tv_usec);
+  payload->tx_sec = htonl(tv.sec());
+  payload->tx_usec = htonl(tv.usec());
 
   unsigned int data_sz = psz - sizeof(click_ether) - sizeof(payload_t);
   if (data_sz > 0)
@@ -391,15 +387,6 @@
 {
   click_chatter("DONE\n");
   router()->please_stop_driver();
-}
-
-struct timeval
-LinkTester::msecs_to_timeval(unsigned int msecs)
-{
-  struct timeval tv;
-  tv.tv_sec = msecs / 1000;
-  tv.tv_usec = 1000 * (msecs % 1000);
-  return tv;
 }
 
 bool
Index: elements/grid/linktester.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/linktester.hh,v
retrieving revision 1.2
diff -u -u -w -r1.2 linktester.hh
--- elements/grid/linktester.hh	3 May 2004 06:04:22 -0000	1.2
+++ elements/grid/linktester.hh	30 Dec 2004 23:50:29 -0000
@@ -100,10 +100,10 @@
 
   bool experiment_params_ok(ErrorHandler *);
 
-  void handle_timer_waiting(const struct timeval &tv);
-  void handle_timer_listening(const struct timeval &tv);
-  void handle_timer_bcast(const struct timeval &tv);
-  void handle_timer_unicast(const struct timeval &tv);
+  void handle_timer_waiting(const Timestamp &tv);
+  void handle_timer_listening(const Timestamp &tv);
+  void handle_timer_bcast(const Timestamp &tv);
+  void handle_timer_unicast(const Timestamp &tv);
 
   // msecs, including any internal pad times, e.g. between broadcast
   // and unicast phases, but not including pads at either end of
@@ -116,20 +116,18 @@
 
   // time at which (before which) to send the first (last) packet of the iter'th iteration
   // before => first broadcast set, !before => second broadcast set
-  struct timeval first_unicast_time(unsigned int iter);
-  struct timeval first_bcast_time(unsigned int iter, bool before);
-  struct timeval last_unicast_time(unsigned int iter);
-  struct timeval last_bcast_time(unsigned int iter, bool before);
+  Timestamp first_unicast_time(unsigned int iter);
+  Timestamp first_bcast_time(unsigned int iter, bool before);
+  Timestamp last_unicast_time(unsigned int iter);
+  Timestamp last_bcast_time(unsigned int iter, bool before);
 
-  void send_unicast_packet(const struct timeval &, 
+  void send_unicast_packet(const Timestamp &, 
 			   unsigned int seq, unsigned int iter);
-  void send_broadcast_packet(unsigned short psz, const struct timeval &,
+  void send_broadcast_packet(unsigned short psz, const Timestamp &,
 			     bool before, unsigned int seq, unsigned int iter);
 
   void finish_experiment();
 
-  static struct timeval msecs_to_timeval(unsigned int msecs);
-
   bool init_random();
   double draw_random(double lambda);
 
@@ -146,7 +144,7 @@
   };
 
   int _start_time; // unix epoch seconds
-  struct timeval _start_time_tv;
+  Timestamp _start_time_tv;
   class EtherAddress _src_eth;
   class EtherAddress _dst_eth;
   class Timer _timer;
@@ -174,8 +172,8 @@
 
   unsigned char *_data_buf;
 
-  struct timeval _last_time;  // when timer was actually last fired
-  struct timeval _next_time;  // when we *want* the next packet to be sent
+  Timestamp _last_time;		// when timer was actually last fired
+  Timestamp _next_time;		// when we *want* the next packet to be sent
 
 };
 
Index: elements/grid/linktestreceiver.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/linktestreceiver.cc,v
retrieving revision 1.1
diff -u -u -w -r1.1 linktestreceiver.cc
--- elements/grid/linktestreceiver.cc	22 Jan 2003 15:32:29 -0000	1.1
+++ elements/grid/linktestreceiver.cc	30 Dec 2004 23:50:29 -0000
@@ -80,9 +80,8 @@
 
   LinkTester::payload_t *payload = (LinkTester::payload_t *) (eh + 1);
   
-  struct timeval &tv = p->timestamp_anno();
-  click_chatter("%u.%06u,%u.%06u,%s,%s,%hu,%d,%u,%u\n",
-		tv.tv_sec, tv.tv_usec,
+  click_chatter("%{timestamp},%u.%06u,%s,%s,%hu,%d,%u,%u\n",
+		&p->timestamp_anno(),
 		ntohl(payload->tx_sec), ntohl(payload->tx_usec),
 		src.s().cc(), dst.s().cc(), ntohs(payload->size),
 		payload->before ? 1 : 0, ntohl(payload->iteration), 
Index: elements/grid/locqueryresponder.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/locqueryresponder.cc,v
retrieving revision 1.29
diff -u -u -w -r1.29 locqueryresponder.cc
--- elements/grid/locqueryresponder.cc	24 Jun 2004 00:03:57 -0000	1.29
+++ elements/grid/locqueryresponder.cc	30 Dec 2004 23:50:29 -0000
@@ -122,9 +122,7 @@
   ASSERT_ALIGNED(q->data());
   q->pull(2);
 
-  struct timeval tv;
-  click_gettimeofday(&tv);
-  p->set_timestamp_anno(tv);
+  p->set_timestamp_anno(Timestamp::now());
 
   memset(q->data(), 0, q->length());
   e = (click_ether *) q->data();
Index: elements/grid/lookuplocalgridroute.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/lookuplocalgridroute.cc,v
retrieving revision 1.52
diff -u -u -w -r1.52 lookuplocalgridroute.cc
--- elements/grid/lookuplocalgridroute.cc	24 Jun 2004 00:03:57 -0000	1.52
+++ elements/grid/lookuplocalgridroute.cc	30 Dec 2004 23:50:32 -0000
@@ -360,10 +360,8 @@
     // logging
     notify_route_cbs(packet, dest_ip, GRCB::FallbackToGF, 0, 0);
 
-    struct timeval tv = { 0, 0 };
-    click_gettimeofday(&tv);
     if (_log)
-      _log->log_no_route(packet, tv);
+      _log->log_no_route(packet, Timestamp::now());
 
     output(2).push(packet);
   }
Index: elements/grid/lookuplocalgridroute2.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/lookuplocalgridroute2.cc,v
retrieving revision 1.3
diff -u -u -w -r1.3 lookuplocalgridroute2.cc
--- elements/grid/lookuplocalgridroute2.cc	24 Jun 2004 00:03:57 -0000	1.3
+++ elements/grid/lookuplocalgridroute2.cc	30 Dec 2004 23:50:32 -0000
@@ -165,11 +165,8 @@
 
     notify_route_cbs(packet, dest_ip, GRCB::Drop, GRCB::NoLocalRoute, 0);
 
-    if (_log) {
-      struct timeval tv;
-      click_gettimeofday(&tv);
-      _log->log_no_route(packet, tv);
-    }
+    if (_log)
+      _log->log_no_route(packet, Timestamp::now());
 
     packet->kill();
     return 0;
Index: elements/grid/lrhello.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/lrhello.cc,v
retrieving revision 1.29
diff -u -u -w -r1.29 lrhello.cc
--- elements/grid/lrhello.cc	24 Jun 2004 00:03:57 -0000	1.29
+++ elements/grid/lrhello.cc	30 Dec 2004 23:50:32 -0000
@@ -119,10 +119,7 @@
   p->pull(2);
   memset(p->data(), 0, p->length());
 
-  struct timeval tv;
-  int res = gettimeofday(&tv, 0);
-  if (res == 0) 
-    p->set_timestamp_anno(tv);
+  p->set_timestamp_anno(Timestamp::now());
 
   click_ether *eh = (click_ether *) p->data();
   memset(eh->ether_dhost, 0xff, 6); // broadcast
Index: elements/grid/packetlogger.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/packetlogger.hh,v
retrieving revision 1.4
diff -u -u -w -r1.4 packetlogger.hh
--- elements/grid/packetlogger.hh	3 Dec 2004 21:17:00 -0000	1.4
+++ elements/grid/packetlogger.hh	30 Dec 2004 23:50:32 -0000
@@ -46,7 +46,7 @@
   enum { NBYTES = 8 };
 
   struct log_entry {
-    struct timeval timestamp;
+    Timestamp timestamp;
     uint8_t src_mac[6];
     uint8_t bytes[NBYTES];
   };
Index: elements/grid/packetlogger2.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/packetlogger2.hh,v
retrieving revision 1.7
diff -u -u -w -r1.7 packetlogger2.hh
--- elements/grid/packetlogger2.hh	7 Jul 2004 19:47:44 -0000	1.7
+++ elements/grid/packetlogger2.hh	30 Dec 2004 23:50:32 -0000
@@ -57,7 +57,7 @@
   enum { NBYTES = 18 };
   
   struct log_entry {
-    struct timeval timestamp;
+    Timestamp timestamp;
     unsigned length;
     uint8_t anno[Packet::USER_ANNO_SIZE];
     uint8_t bytes[NBYTES];
Index: elements/grid/printgrid.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/printgrid.cc,v
retrieving revision 1.34
diff -u -u -w -r1.34 printgrid.cc
--- elements/grid/printgrid.cc	3 May 2004 06:04:22 -0000	1.34
+++ elements/grid/printgrid.cc	30 Dec 2004 23:50:32 -0000
@@ -103,63 +103,48 @@
 
   String type = grid_hdr::type_string(gh->type);
 
-  String line("PrintGrid ");
+  StringAccum line;
+  line << "PrintGrid ";
   if (_verbose)
-    line += id() + " ";
+      line << id() << " ";
   if (_label[0] != 0)
-    line += _label + " ";
-  if (_timestamp) {
-    char buf[30];
-    snprintf(buf, sizeof(buf), "%ld.%06ld ",
-	     (long) p->timestamp_anno().tv_sec,
-	     (long) p->timestamp_anno().tv_usec);
-    line += buf;
-  }
+      line << _label << " ";
+  if (_timestamp)
+      line << p->timestamp_anno() << ' ';
 
   if (_print_eth) {
-    char buf[100];
-    snprintf(buf, sizeof(buf), "%s %s %04hx ", 
-	     EtherAddress(eh->ether_shost).s().cc(), EtherAddress(eh->ether_dhost).s().cc(),
-	     ntohs(eh->ether_type));
-    line += buf;
+      line << EtherAddress(eh->ether_shost) << ' ' << EtherAddress(eh->ether_dhost) << ' ';
+      line.snprintf(10, "%04hx ", ntohs(eh->ether_type));
   }
 
-  line += ": " + type + " ";
+  line << ": " << type << " ";
   if (_verbose)
-    line += "hdr_len=" + String((unsigned int) gh->hdr_len) + " ";
+      line << "hdr_len="  << gh->hdr_len << " ";
 
   // packet originator info
-  line += "ip=" + IPAddress(gh->ip).s() + " ";
+  line << "ip=" << IPAddress(gh->ip).s() << " ";
   if (_verbose) {
-    if (gh->loc_good) {
-      char buf[50];
-      snprintf(buf, 50, "loc=%s ", gh->loc.s().cc());
-      line += buf;
-      line += "loc_err=" + String(ntohs(gh->loc_err)) + " ";
-    }
+    if (gh->loc_good)
+	line << "loc=" << gh->loc.s() << " loc_err=" << ntohs(gh->loc_err) << ' ';
     else
-      line += "bad-loc ";
-    line += "loc_seq_no=" + String(ntohl(gh->loc_seq_no)) + " ";
+	line << "bad-loc ";
+    line << "loc_seq_no=" << ntohl(gh->loc_seq_no) << " ";
   }
   
   // packet transmitter info
-  line += "tx_ip=" + IPAddress(gh->tx_ip).s() + " ";
+  line << "tx_ip=" << IPAddress(gh->tx_ip) << " ";
   if (_verbose) {
-    if (gh->tx_loc_good) {
-      char buf[50];
-      snprintf(buf, 50, "tx_loc=%s ", gh->tx_loc.s().cc());
-      line += buf;
-      line += "tx_loc_err=" + String(ntohs(gh->tx_loc_err)) + " ";
-    }
+    if (gh->tx_loc_good)
+	line << "tx_loc=" << gh->tx_loc.s() << " tx_loc_err=" << ntohs(gh->tx_loc_err) << ' ';
     else
-      line += "bad-tx-loc ";
-    line += "tx_loc_seq_no=" + String(ntohl(gh->tx_loc_seq_no)) + " ";
+	line << "bad-tx-loc ";
+    line << "tx_loc_seq_no=" << ntohl(gh->tx_loc_seq_no) << " ";
   }
 
   if (_verbose)
-    line += "pkt_len=" + String(ntohs(gh->total_len)) + " ";
+      line << "pkt_len=" << ntohs(gh->total_len) << " ";
 
-  line += "** ";
+  line << "** ";
 
   grid_hello *gh2 = 0;
   grid_nbr_encap *nb = 0;
@@ -171,58 +156,58 @@
 
   case grid_hdr::GRID_LR_HELLO:
     gh2 = (grid_hello *) (gh + 1);
-    line += "seq_no=" + String(ntohl(gh2->seq_no)) + " ";
+    line << "seq_no=" << ntohl(gh2->seq_no) << " ";
     if (_verbose)
-      line += "age=" + String(ntohl(gh2->age)) + " ";
-    line += "num_nbrs=" + String((unsigned int) gh2->num_nbrs);
+	line << "age=" << ntohl(gh2->age) << " ";
+    line << "num_nbrs=" << (unsigned int) gh2->num_nbrs;
     if (_print_routes)
-      line += get_entries(gh2);
+	line << get_entries(gh2);
     break;
 
   case grid_hdr::GRID_NBR_ENCAP:
   case grid_hdr::GRID_LOC_REPLY:
     nb = (grid_nbr_encap *) (gh + 1);
-    line += encap_to_string(nb);
+    line << encap_to_string(nb);
     break;
 
   case grid_hdr::GRID_LOC_QUERY:
     lq = (grid_loc_query *) (gh + 1);
-    line += "dst_ip=" + IPAddress(lq->dst_ip).s() + " ";
-    line += "seq_no=" + String(ntohl(lq->seq_no));
+    line << "dst_ip=" << IPAddress(lq->dst_ip) << " "
+	 << "seq_no=" << ntohl(lq->seq_no);
     break;
 
   case grid_hdr::GRID_ROUTE_PROBE: 
     nb = (grid_nbr_encap *) (gh + 1);
-    line += encap_to_string(nb);
+    line << encap_to_string(nb);
     rp = (grid_route_probe *) (nb + 1);
-    line += " nonce=" + String(ntohl(rp->nonce));
+    line << " nonce=" << ntohl(rp->nonce);
     break;
 
   case grid_hdr::GRID_ROUTE_REPLY: 
     nb = (grid_nbr_encap *) (gh + 1);
-    line += encap_to_string(nb);
+    line << encap_to_string(nb);
     rr = (grid_route_reply *) (nb + 1);
-    line += " nonce=" + String(ntohl(rr->nonce));
-    line += " probe_dest=" + IPAddress(rr->probe_dest).s();
-    line += " reply_hop=" + String((unsigned int) rr->reply_hop);
+    line << " nonce=" << ntohl(rr->nonce)
+	 << " probe_dest=" << IPAddress(rr->probe_dest)
+	 << " reply_hop=" << (unsigned int) rr->reply_hop;
     break;
 
   case grid_hdr::GRID_LINK_PROBE: {
     grid_link_probe *lp = (grid_link_probe *) (gh + 1);
-    line += " seq_no=" + String(ntohl(lp->seq_no));
-    line += " period=" + String(ntohl(lp->period));
-    line += " tau=" + String(ntohl(lp->tau));
-    line += " num_links=" + String(ntohl(lp->num_links));
+    line << " seq_no=" << ntohl(lp->seq_no)
+	 << " period=" << ntohl(lp->period)
+	 << " tau=" << ntohl(lp->tau)
+	 << " num_links=" << ntohl(lp->num_links);
     if (_print_probe_entries)
-      line += get_probe_entries(lp);
+	line << get_probe_entries(lp);
     break;
   }
 
   default:
-    line += "Unknown grid header type " + String((int) gh->type);
+    line << "Unknown grid header type " << (int) gh->type;
   }
   
-  click_chatter("%s", line.cc());
+  click_chatter("%s", line.c_str());
 
   return p;
 }
@@ -236,13 +221,8 @@
     line << id() << " ";
   if (_label[0] != 0)
     line << _label << " ";
-  if (_timestamp) {
-    char buf[30];
-    snprintf(buf, sizeof(buf), "%ld.%06ld ",
-	     (long) p->timestamp_anno().tv_sec,
-	     (long) p->timestamp_anno().tv_usec);
-    line << buf;
-  }
+  if (_timestamp)
+      line << p->timestamp_anno();
 
   unsigned min_sz = sizeof(click_ether) + LinkStat::link_probe::size;
   if (p->length() < min_sz) {
@@ -320,38 +300,30 @@
 String
 PrintGrid::get_entries(const grid_hello *gh) const
 {
-  String ret;
+  StringAccum ret;
   char *cp = (char *) (gh + 1);
   for (int i = 0; i < gh->num_nbrs; i++) {
     grid_nbr_entry *na = (grid_nbr_entry *) (cp + gh->nbr_entry_sz * i);
-    char buf[1024];
-    snprintf(buf, sizeof(buf), "\n\tip=%s next=%s hops=%d seq=%lu ",
-	     IPAddress(na->ip).s().cc(),
-	     IPAddress(na->next_hop_ip).s().cc(),
-	     (int) na->num_hops,
-	     (unsigned long) ntohl(na->seq_no));
-    ret += buf;
-
-    if (na->metric_valid) {
-      snprintf(buf, sizeof(buf), "metric=%lu", (unsigned long) ntohl(na->metric));
-      ret += buf;
-    }
+    ret << "\n\tip=" << IPAddress(na->ip)
+	<< " next=" << IPAddress(na->next_hop_ip)
+	<< " hops=" << (int) na->num_hops
+	<< " seq=" << (unsigned) ntohl(na->seq_no) << ' ';
+
+    if (na->metric_valid)
+	ret << "metric=" << (unsigned) ntohl(na->metric);
     else
-      ret += "bad-metric";
+	ret << "bad-metric";
 
     if (_verbose) {
-      ret += String(" gw=") + (na->is_gateway ? "yes" : "no");
-      ret += String(" ttl=") + String(ntohl(na->ttl));
-      if (na->loc_good) {
-	snprintf(buf, sizeof(buf), " loc=%s loc_err=%us",
-		 na->loc.s().cc(), ntohs(na->loc_err));
-	ret += buf;
-      }
+	ret << " gw=" << (na->is_gateway ? "yes" : "no")
+	    << " ttl=" << ntohl(na->ttl);
+      if (na->loc_good)
+	  ret << " loc=" << na->loc.s() << " loc_err=" << (unsigned short) na->loc_err;
       else
-	ret += " bad-loc";
+	  ret << " bad-loc";
     }
   }
-  return ret;
+  return ret.take_string();
 }
 
 CLICK_ENDDECLS
Index: elements/grid/timeutils.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/timeutils.hh,v
retrieving revision 1.9
diff -u -u -w -r1.9 timeutils.hh
--- elements/grid/timeutils.hh	25 Aug 2003 01:23:13 -0000	1.9
+++ elements/grid/timeutils.hh	30 Dec 2004 23:50:32 -0000
@@ -30,33 +30,5 @@
   return tv2;
 }
 
-inline String
-timeval_to_str(const timeval &tv)
-{
-  char buf[80];
-  snprintf(buf, sizeof(buf), "%ld.%06ld", (long) tv.tv_sec, (long) tv.tv_usec);
-  return buf;
-}
-
-#ifdef CLICK_USERLEVEL
-inline timeval
-double_to_timeval(double t)
-{
-  timeval tv;
-  tv.tv_sec = (time_t) floor(t);
-  double frac = t - tv.tv_sec;
-  tv.tv_usec = (long) (frac * 1e6);
-  return tv;
-}
-
-inline double
-timeval_to_double(const timeval &tv)
-{
-  double d = tv.tv_sec;
-  double frac = tv.tv_usec;
-  return d + frac * 1e-6;
-}
-#endif
-
 CLICK_ENDDECLS
 #endif 
Index: elements/grid/updateroutes.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/grid/updateroutes.cc,v
retrieving revision 1.34
diff -u -u -w -r1.34 updateroutes.cc
--- elements/grid/updateroutes.cc	24 Jun 2004 00:03:57 -0000	1.34
+++ elements/grid/updateroutes.cc	30 Dec 2004 23:50:32 -0000
@@ -540,10 +540,7 @@
   p->pull(2);
   memset(p->data(), 0, p->length());
 
-  struct timeval tv;
-  int res = gettimeofday(&tv, 0);
-  if (res == 0) 
-    p->set_timestamp_anno(tv);
+  p->set_timestamp_anno(Timestamp::now());
 
   click_ether *eh = (click_ether *) p->data();
   memset(eh->ether_dhost, 0xff, 6); // broadcast
Index: elements/icmp/icmperror.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/icmp/icmperror.cc,v
retrieving revision 1.21
diff -u -u -w -r1.21 icmperror.cc
--- elements/icmp/icmperror.cc	18 Dec 2004 02:30:24 -0000	1.21
+++ elements/icmp/icmperror.cc	30 Dec 2004 23:50:32 -0000
@@ -334,7 +334,7 @@
   // set annotations
   q->set_dst_ip_anno(IPAddress(nip->ip_dst));
   SET_FIX_IP_SRC_ANNO(q, 1);
-  click_gettimeofday(&q->timestamp_anno());
+  q->timestamp_anno().set_now();
 
  out:
   p->kill();
Index: elements/icmp/icmppingresponder.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/icmp/icmppingresponder.cc,v
retrieving revision 1.12
diff -u -u -w -r1.12 icmppingresponder.cc
--- elements/icmp/icmppingresponder.cc	3 May 2004 06:04:23 -0000	1.12
+++ elements/icmp/icmppingresponder.cc	30 Dec 2004 23:50:32 -0000
@@ -84,7 +84,7 @@
     // set annotations
     // (dst_ip_anno bug reported by Sven Hirsch <hirschs at gmx.de>)
     q->set_dst_ip_anno(iph->ip_dst);
-    click_gettimeofday(&q->timestamp_anno());
+    q->timestamp_anno().set_now();
     SET_PAINT_ANNO(q, 0);
 
     // set ICMP packet type to ICMP_ECHOREPLY and recalculate checksum
Index: elements/icmp/icmpsendpings.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/icmp/icmpsendpings.cc,v
retrieving revision 1.32
diff -u -u -w -r1.32 icmpsendpings.cc
--- elements/icmp/icmpsendpings.cc	17 May 2004 05:46:38 -0000	1.32
+++ elements/icmp/icmpsendpings.cc	30 Dec 2004 23:50:32 -0000
@@ -150,7 +150,7 @@
     
     q->set_dst_ip_anno(IPAddress(_dst));
     q->set_ip_header(nip, sizeof(click_ip));
-    click_gettimeofday(&q->timestamp_anno());
+    q->timestamp_anno().set_now();
 
     if (_receiver)
 	_receiver->send_timestamp[icp->icmp_sequence] = q->timestamp_anno();
@@ -171,18 +171,18 @@
 	&& p->transport_length() >= (int)sizeof(click_icmp_echo)
 	&& icmph->icmp_type == ICMP_ECHOREPLY
 	&& icmph->icmp_identifier == _icmp_id) {
-	struct timeval *send_ts = &_receiver->send_timestamp[icmph->icmp_sequence];
+	Timestamp *send_ts = &_receiver->send_timestamp[icmph->icmp_sequence];
 	
-	if (!timerisset(send_ts))
+	if (!*send_ts)
 	    /* error */;
 	else {
-	    if (send_ts->tv_usec >= 1000000) {
+	    if (send_ts->_subsec < 0) {
 		_receiver->nduplicate++;
-		send_ts->tv_usec -= 1000000;
+		send_ts->_subsec ^= 0xFFFFFFFF;
 	    }
 	    
-	    struct timeval diff = p->timestamp_anno() - *send_ts;
-	    uint32_t diffval = (diff.tv_sec * 1000000) + diff.tv_usec;
+	    Timestamp diff = p->timestamp_anno() - *send_ts;
+	    uint32_t diffval = diff.usec1();
 	    if (diffval < _receiver->time_min || !_receiver->nreceived)
 		_receiver->time_min = diffval;
 	    if (diffval > _receiver->time_max || !_receiver->nreceived)
@@ -191,7 +191,7 @@
 	    _receiver->time_sq_sum += ((counter_t)diffval) * diffval;
 
 	    _receiver->nreceived++;
-	    send_ts->tv_usec += 1000000;
+	    send_ts->_subsec ^= 0xFFFFFFFF;
 	    
 #ifdef __linux__
 	    uint16_t readable_seq = icmph->icmp_sequence;
@@ -199,7 +199,7 @@
 	    uint16_t readable_seq = ntohs(icmph->icmp_sequence);
 #endif
 	    if (_verbose)
-		click_chatter("%s: %d bytes from %s: icmp_seq=%u ttl=%u time=%d.%d ms", declaration().c_str(), ntohs(iph->ip_len) - (iph->ip_hl << 2) - sizeof(*icmph), IPAddress(iph->ip_dst).s().c_str(), readable_seq, iph->ip_ttl, (unsigned)(diffval/1000), (unsigned)(diffval % 1000));
+		click_chatter("%s: %d bytes from %s: icmp_seq=%u ttl=%u time=%d.%03d ms", declaration().c_str(), ntohs(iph->ip_len) - (iph->ip_hl << 2) - sizeof(*icmph), IPAddress(iph->ip_dst).s().c_str(), readable_seq, iph->ip_ttl, (unsigned)(diffval/1000), (unsigned)(diffval % 1000));
 	}
     }
     p->kill();
Index: elements/icmp/icmpsendpings.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/icmp/icmpsendpings.hh,v
retrieving revision 1.16
diff -u -u -w -r1.16 icmpsendpings.hh
--- elements/icmp/icmpsendpings.hh	20 May 2004 08:17:14 -0000	1.16
+++ elements/icmp/icmpsendpings.hh	30 Dec 2004 23:50:32 -0000
@@ -146,7 +146,7 @@
 	uint32_t time_max;
 	counter_t time_sum;
 	counter_t time_sq_sum;
-	struct timeval send_timestamp[65536];
+	Timestamp send_timestamp[65536];
     };
     ReceiverInfo *_receiver;
 
Index: elements/ip/ipgwoptions.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/ip/ipgwoptions.cc,v
retrieving revision 1.36
diff -u -u -w -r1.36 ipgwoptions.cc
--- elements/ip/ipgwoptions.cc	24 Jun 2004 00:03:58 -0000	1.36
+++ elements/ip/ipgwoptions.cc	30 Dec 2004 23:50:33 -0000
@@ -122,9 +122,8 @@
       int flg = oa[oi+3] & 0xf;
       bool overflowed = 0;
 
-      struct timeval tv;
-      click_gettimeofday(&tv);
-      int ms = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
+      Timestamp now = Timestamp::now();
+      int ms = htonl((now.sec() % 86400)*1000 + now.msec());
 
       if(p < 4){
 	oi += 2;
Index: elements/ip/ipoutputcombo.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/ip/ipoutputcombo.cc,v
retrieving revision 1.23
diff -u -u -w -r1.23 ipoutputcombo.cc
--- elements/ip/ipoutputcombo.cc	24 Jun 2004 00:03:58 -0000	1.23
+++ elements/ip/ipoutputcombo.cc	30 Dec 2004 23:50:33 -0000
@@ -122,9 +122,8 @@
 	int flg = woa[oi+3] & 0xf;
 	bool overflowed = 0;
 
-	struct timeval tv;
-	click_gettimeofday(&tv);
-	int ms = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
+	Timestamp now = Timestamp::now();
+	int ms = htonl((now.sec() % 86400)*1000 + now.msec());
 
 	if(p < 4){
 	  problem_offset = oi + 2;
Index: elements/ip/ipreassembler.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/ip/ipreassembler.cc,v
retrieving revision 1.20
diff -u -u -w -r1.20 ipreassembler.cc
--- elements/ip/ipreassembler.cc	21 Sep 2004 19:31:47 -0000	1.20
+++ elements/ip/ipreassembler.cc	30 Dec 2004 23:50:33 -0000
@@ -237,10 +237,10 @@
 	return p;
 
     // reap if necessary
-    int now = p->timestamp_anno().tv_sec;
+    int now = p->timestamp_anno().sec();
     if (!now) {
-	click_gettimeofday(&p->timestamp_anno());
-	now = p->timestamp_anno().tv_sec;
+	p->timestamp_anno().set_now();
+	now = p->timestamp_anno().sec();
     }
     if (now >= _reap_time)
 	reap(now);
@@ -371,7 +371,7 @@
 	for (int bucket = 0; bucket < NMAP; bucket++) {
 	    WritablePacket **pprev = &_map[bucket];
 	    for (WritablePacket *q = *pprev; q; q = *pprev)
-		if (q->timestamp_anno().tv_sec < now - delta) {
+		if (q->timestamp_anno().sec() < now - delta) {
 		    *pprev = (WritablePacket *)q->next();
 		    _mem_used -= IPH_MEM_USED + q->transport_length();
 		    q->set_next(0);
@@ -395,7 +395,7 @@
     for (int i = 0; i < NMAP; i++) {
 	WritablePacket **q_pprev = &_map[i];
 	for (WritablePacket *q = *q_pprev; q; ) {
-	    if (q->timestamp_anno().tv_sec < kill_time) {
+	    if (q->timestamp_anno().sec() < kill_time) {
 		*q_pprev = (WritablePacket *)q->next();
 		q->set_next(0);
 		checked_output_push(1, q);
Index: elements/ip/trieiplookup.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/ip/trieiplookup.cc,v
retrieving revision 1.5
diff -u -u -w -r1.5 trieiplookup.cc
--- elements/ip/trieiplookup.cc	7 Jul 2004 16:04:59 -0000	1.5
+++ elements/ip/trieiplookup.cc	30 Dec 2004 23:50:33 -0000
@@ -247,9 +247,8 @@
 void
 TrieIPLookup::build_main()
 {
-    struct timeval tv;
-    click_gettimeofday(&tv);
-    click_chatter("starting to init data structure: %d\n", tv.tv_sec);
+    Timestamp ts = Timestamp::now();
+    click_chatter("starting to init data structure: %d\n", ts.sec());
 
     check_route_vector_sorted();
 
@@ -258,22 +257,22 @@
     build_init();
     check_init();
 
-    click_gettimeofday(&tv);
-    click_chatter("starting to build trie: %d\n", tv.tv_sec);
+    ts = Timestamp::now();
+    click_chatter("starting to build trie: %d\n", ts.sec());
 
     // build trie
     build_trie();
     check_trie(_trie_vector[0]);
 
-    click_gettimeofday(&tv);
-    click_chatter("starting to set children lengths: %d\n", tv.tv_sec);
+    ts = Timestamp::now();
+    click_chatter("starting to set children lengths: %d\n", ts.sec());
 
     // set children lengths
     build_children_lengths(0);
     check_lengths(_trie_vector[0]);
 
-    click_gettimeofday(&tv);
-    click_chatter("starting to rebuild hash: %d\n", tv.tv_sec);
+    ts = Timestamp::now();
+    click_chatter("starting to rebuild hash: %d\n", ts.sec());
 
     // rebuild hash
     for (int i = 0; i <= 32; i++) {
@@ -281,8 +280,8 @@
     }
     build_hash(0);
 
-    click_gettimeofday(&tv);
-    click_chatter("done initializaton: %d\n", tv.tv_sec);
+    ts = Timestamp::now();
+    click_chatter("done initializaton: %d\n", ts.sec());
 
     _trie_vector.clear();
 }
Index: elements/linuxmodule/fasttcpflows.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/linuxmodule/fasttcpflows.cc,v
retrieving revision 1.13
diff -u -u -w -r1.13 fasttcpflows.cc
--- elements/linuxmodule/fasttcpflows.cc	1 Dec 2004 20:03:40 -0000	1.13
+++ elements/linuxmodule/fasttcpflows.cc	30 Dec 2004 23:50:33 -0000
@@ -305,9 +305,7 @@
     return 0;
 
   if(_rate_limited){
-    struct timeval now;
-    click_gettimeofday(&now);
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
       _rate.update();
       p = get_packet();
     }
Index: elements/linuxmodule/fastudpflows.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/linuxmodule/fastudpflows.cc,v
retrieving revision 1.13
diff -u -u -w -r1.13 fastudpflows.cc
--- elements/linuxmodule/fastudpflows.cc	24 Jun 2004 00:03:58 -0000	1.13
+++ elements/linuxmodule/fastudpflows.cc	30 Dec 2004 23:50:33 -0000
@@ -187,9 +187,7 @@
   if (!_active || (_limit != NO_LIMIT && _count >= _limit)) return 0;
 
   if(_rate_limited){
-    struct timeval now;
-    click_gettimeofday(&now);
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
       _rate.update();
       p = get_packet();
     }
Index: elements/linuxmodule/fastudpsrc.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/linuxmodule/fastudpsrc.cc,v
retrieving revision 1.19
diff -u -u -w -r1.19 fastudpsrc.cc
--- elements/linuxmodule/fastudpsrc.cc	1 Dec 2004 20:03:40 -0000	1.19
+++ elements/linuxmodule/fastudpsrc.cc	30 Dec 2004 23:50:33 -0000
@@ -164,9 +164,7 @@
   if (!_active || (_limit != NO_LIMIT && _count >= _limit)) return 0;
 
   if(_rate_limited){
-    struct timeval now;
-    click_gettimeofday(&now);
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
       _rate.update();
       atomic_inc(&_skb->users); 
       p = reinterpret_cast<Packet *>(_skb);
Index: elements/linuxmodule/fastudpsrcip6.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/linuxmodule/fastudpsrcip6.cc,v
retrieving revision 1.18
diff -u -u -w -r1.18 fastudpsrcip6.cc
--- elements/linuxmodule/fastudpsrcip6.cc	24 Jun 2004 00:03:58 -0000	1.18
+++ elements/linuxmodule/fastudpsrcip6.cc	30 Dec 2004 23:50:33 -0000
@@ -164,9 +164,7 @@
   if (!_active || (_limit != NO_LIMIT && _count >= _limit)) return 0;
 
   if(_rate_limited){
-    struct timeval now;
-    click_gettimeofday(&now);
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
       _rate.update();
       atomic_inc(&_skb->users); 
       p = reinterpret_cast<Packet *>(_skb);
Index: elements/linuxmodule/polldevice.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/linuxmodule/polldevice.cc,v
retrieving revision 1.137
diff -u -u -w -r1.137 polldevice.cc
--- elements/linuxmodule/polldevice.cc	7 Jul 2004 15:30:34 -0000	1.137
+++ elements/linuxmodule/polldevice.cc	30 Dec 2004 23:50:33 -0000
@@ -275,8 +275,7 @@
     Packet *p = Packet::make(skb); 
    
 # ifndef CLICK_WARP9
-    struct timeval &tv = p->timestamp_anno(); 
-    click_gettimeofday(&tv);
+    p->timestamp_anno().set_now();
 # endif
 
     _npackets++;
Index: elements/standard/bandwidthshaper.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/bandwidthshaper.cc,v
retrieving revision 1.14
diff -u -u -w -r1.14 bandwidthshaper.cc
--- elements/standard/bandwidthshaper.cc	7 Jul 2004 16:06:08 -0000	1.14
+++ elements/standard/bandwidthshaper.cc	30 Dec 2004 23:50:33 -0000
@@ -36,9 +36,7 @@
 BandwidthShaper::pull(int)
 {
     Packet *p = 0;
-    struct timeval now;
-    click_gettimeofday(&now);
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
 	if ((p = input(0).pull()))
 	    _rate.update_with(p->length());
     }
Index: elements/standard/bwratedsplitter.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/bwratedsplitter.cc,v
retrieving revision 1.9
diff -u -u -w -r1.9 bwratedsplitter.cc
--- elements/standard/bwratedsplitter.cc	7 Jul 2004 16:06:08 -0000	1.9
+++ elements/standard/bwratedsplitter.cc	30 Dec 2004 23:50:33 -0000
@@ -33,9 +33,7 @@
 void
 BandwidthRatedSplitter::push(int, Packet *p)
 {
-    struct timeval now;
-    click_gettimeofday(&now);
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
 	_rate.update_with(p->length());
 	output(0).push(p);
     } else
Index: elements/standard/bwratedunqueue.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/bwratedunqueue.cc,v
retrieving revision 1.15
diff -u -u -w -r1.15 bwratedunqueue.cc
--- elements/standard/bwratedunqueue.cc	7 Jul 2004 16:06:08 -0000	1.15
+++ elements/standard/bwratedunqueue.cc	30 Dec 2004 23:50:33 -0000
@@ -34,10 +34,8 @@
 bool
 BandwidthRatedUnqueue::run_task()
 {
-    struct timeval now;
-    click_gettimeofday(&now);
     bool worked = false;
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
 	if (Packet *p = input(0).pull()) {
 	    _rate.update_with(p->length());
 	    worked = true;
Index: elements/standard/delayshaper.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/delayshaper.cc,v
retrieving revision 1.13
diff -u -u -w -r1.13 delayshaper.cc
--- elements/standard/delayshaper.cc	24 Jun 2004 00:04:17 -0000	1.13
+++ elements/standard/delayshaper.cc	30 Dec 2004 23:50:33 -0000
@@ -58,7 +58,7 @@
 {
     ActiveNotifier::initialize(router());
     return cp_va_parse(conf, this, errh,
-		       cpInterval, "delay", &_delay, cpEnd);
+		       cpTimestamp, "delay", &_delay, cpEnd);
 }
 
 int
@@ -81,23 +81,22 @@
 {
     // read a packet
     if (!_p && (_p = input(0).pull())) {
-	if (!_p->timestamp_anno().tv_sec) // get timestamp if not set
-	    click_gettimeofday(&_p->timestamp_anno());
+	if (!_p->timestamp_anno()._sec) // get timestamp if not set
+	    _p->timestamp_anno().set_now();
 	_p->timestamp_anno() += _delay;
     }
     
     if (_p) {
-	struct timeval now, diff;
-	click_gettimeofday(&now);
-	diff = _p->timestamp_anno() - now;
+	Timestamp now = Timestamp::now();
+	Timestamp diff = _p->timestamp_anno() - now;;
 	
-	if (diff.tv_sec < 0 || (diff.tv_sec == 0 && diff.tv_usec == 0)) {
+	if (diff._sec < 0 || (diff._sec == 0 && diff._subsec == 0)) {
 	    // packet ready for output
 	    Packet *p = _p;
 	    p->timestamp_anno() = now;
 	    _p = 0;
 	    return p;
-	} else if (diff.tv_sec == 0 && diff.tv_usec < 100000) {
+	} else if (diff._sec == 0 && diff._subsec < Timestamp::usec_to_subsec(100000)) {
 	    // small delta, don't go to sleep -- but mark our Signal as active,
 	    // since we have something ready. NB: should not wake listeners --
 	    // we are in pull()!
@@ -132,8 +131,8 @@
 DelayShaper::write_param(const String &s, Element *e, void *, ErrorHandler *errh)
 {
     DelayShaper *u = (DelayShaper *)e;
-    if (!cp_timeval(cp_uncomment(s), &u->_delay))
-	return errh->error("delay must be a timeval");
+    if (!cp_time(cp_uncomment(s), &u->_delay))
+	return errh->error("delay must be a timestamp");
     return 0;
 }
 
Index: elements/standard/delayshaper.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/delayshaper.hh,v
retrieving revision 1.11
diff -u -u -w -r1.11 delayshaper.hh
--- elements/standard/delayshaper.hh	20 May 2004 18:08:36 -0000	1.11
+++ elements/standard/delayshaper.hh	30 Dec 2004 23:50:33 -0000
@@ -58,7 +58,7 @@
   private:
 
     Packet *_p;
-    struct timeval _delay;
+    Timestamp _delay;
     Timer _timer;
     NotifierSignal _upstream_signal;
 
Index: elements/standard/delayunqueue.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/delayunqueue.cc,v
retrieving revision 1.20
diff -u -u -w -r1.20 delayunqueue.cc
--- elements/standard/delayunqueue.cc	24 Jun 2004 00:04:17 -0000	1.20
+++ elements/standard/delayunqueue.cc	30 Dec 2004 23:50:33 -0000
@@ -66,24 +66,23 @@
  retry:
   // read a packet
   if (!_p && (_p = input(0).pull())) {
-    if (!_p->timestamp_anno().tv_sec) // get timestamp if not set
-      click_gettimeofday(&_p->timestamp_anno());
+	if (!_p->timestamp_anno()._sec) // get timestamp if not set
+	    _p->timestamp_anno().set_now();
     _p->timestamp_anno() += _delay;
   }
   
   if (_p) {
-    struct timeval now, diff;
-    click_gettimeofday(&now);
-    diff = _p->timestamp_anno() - now;
+	Timestamp now = Timestamp::now();
+	Timestamp diff = _p->timestamp_anno() - now;
 
-    if (diff.tv_sec < 0 || (diff.tv_sec == 0 && diff.tv_usec == 0)) {
+	if (diff._sec < 0 || (diff._sec == 0 && diff._subsec == 0)) {
       // packet ready for output
       _p->timestamp_anno() = now;
       output(0).push(_p);
       _p = 0;
       worked = true;
       goto retry;
-    } else if (diff.tv_sec == 0 && diff.tv_usec < 100000)
+	} else if (diff._sec == 0 && diff._subsec < Timestamp::usec_to_subsec(100000))
       // small delta, reschedule Task
       /* Task rescheduled below */;
     else {
Index: elements/standard/delayunqueue.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/delayunqueue.hh,v
retrieving revision 1.14
diff -u -u -w -r1.14 delayunqueue.hh
--- elements/standard/delayunqueue.hh	3 May 2004 06:04:48 -0000	1.14
+++ elements/standard/delayunqueue.hh	30 Dec 2004 23:50:33 -0000
@@ -47,7 +47,7 @@
  private:
 
   Packet *_p;
-  struct timeval _delay;
+    Timestamp _delay;
   Task _task;
   Timer _timer;
   NotifierSignal _signal;
Index: elements/standard/drivermanager.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/drivermanager.cc,v
retrieving revision 1.37
diff -u -u -w -r1.37 drivermanager.cc
--- elements/standard/drivermanager.cc	30 Jul 2004 20:50:58 -0000	1.37
+++ elements/standard/drivermanager.cc	30 Dec 2004 23:50:33 -0000
@@ -101,9 +101,9 @@
 #endif
 	    
 	} else if (insn_name == "wait_time" || insn_name == "wait_for" || insn_name == "wait") {
-	    timeval tv;
-	    if (cp_timeval(conf[i], &tv))
-		add_insn(INSN_WAIT_TIME, tv.tv_sec, tv.tv_usec);
+	    Timestamp ts;
+	    if (cp_time(conf[i], &ts))
+		add_insn(INSN_WAIT_TIME, ts.sec(), ts.subsec());
 	    else
 		errh->error("expected '%s TIME'", insn_name.cc());
 
@@ -180,7 +180,7 @@
     int insn = _insns[_insn_pos];
     assert(insn <= INSN_WAIT_TIME);
     if (insn == INSN_WAIT_TIME)
-	_timer.schedule_after(make_timeval(_args[_insn_pos], _args2[_insn_pos]));
+	_timer.schedule_after(Timestamp(_args[_insn_pos], _args2[_insn_pos]));
     else if (insn == INSN_INITIAL)
 	// get rid of the initial runcount so we get called right away
 	router()->adjust_runcount(-1);
@@ -255,7 +255,7 @@
 	router()->adjust_runcount(-1);
 	return false;
       case INSN_WAIT_TIME:
-	_timer.schedule_after(make_timeval(_args[_insn_pos], _args2[_insn_pos]));
+	_timer.schedule_after(Timestamp(_args[_insn_pos], _args2[_insn_pos]));
 	return false;
       case INSN_WAIT_STOP:
       default:
Index: elements/standard/infinitesource.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/infinitesource.cc,v
retrieving revision 1.49
diff -u -u -w -r1.49 infinitesource.cc
--- elements/standard/infinitesource.cc	15 Nov 2004 01:34:02 -0000	1.49
+++ elements/standard/infinitesource.cc	30 Dec 2004 23:50:33 -0000
@@ -116,7 +116,7 @@
   if (n > 0) {
     for (int i = 0; i < n; i++) {
       Packet *p = _packet->clone();
-      click_gettimeofday(&p->timestamp_anno());
+      p->timestamp_anno().set_now();
       output(0).push(p);
     }
     _count += n;
@@ -149,7 +149,7 @@
   }
   _count++;
   Packet *p = _packet->clone();
-  click_gettimeofday(&p->timestamp_anno());
+  p->timestamp_anno().set_now();
   return p;
 }
 
Index: elements/standard/linkunqueue.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/linkunqueue.cc,v
retrieving revision 1.5
diff -u -u -w -r1.5 linkunqueue.cc
--- elements/standard/linkunqueue.cc	24 Jun 2004 00:04:17 -0000	1.5
+++ elements/standard/linkunqueue.cc	30 Dec 2004 23:50:33 -0000
@@ -84,39 +84,34 @@
 }
 
 void
-LinkUnqueue::delay_by_bandwidth(Packet *p, const struct timeval &tv) const
+LinkUnqueue::delay_by_bandwidth(Packet *p, const Timestamp &tv) const
 {
     uint32_t length = p->length() + EXTRA_LENGTH_ANNO(p);
     uint32_t delay = (length * 10000) / _bandwidth;
-    struct timeval &timestamp = p->timestamp_anno();
+    Timestamp &timestamp = p->timestamp_anno();
     timestamp = tv;
     if (delay >= 1000000) {
-	timestamp.tv_sec += delay / 1000000;
-	timestamp.tv_usec += delay % 1000000;
+	timestamp._sec += delay / 1000000;
+	timestamp._subsec += Timestamp::usec_to_subsec(delay % 1000000);
     } else
-	timestamp.tv_usec += delay;
-    if (timestamp.tv_usec >= 1000000)
-	timestamp.tv_sec++, timestamp.tv_usec -= 1000000;
+	timestamp._subsec += Timestamp::usec_to_subsec(delay);
+    timestamp.add_fix();
 }
 
 #if 0
 #include <click/straccum.hh>
 static void print_queue(Packet *head) {
-    static struct timeval first;
-    if (!timerisset(&first) && head)
+    static Timestamp first;
+    if (!first && head)
 	first = head->timestamp_anno();
     StringAccum sa;
     sa << '[';
     while (head) {
-	struct timeval diff = head->timestamp_anno() - first;
+	Timestamp diff = head->timestamp_anno() - first;
 	sa << ' ' << diff;
 	head = head->next();
     }
-    sa << ' ' << ']';
-    struct timeval now;
-    click_gettimeofday(&now);
-    now = now - first;
-    sa << ' ' << '@' << now;
+    sa << ' ' << ']' << ' ' << '@' << (Timestamp::now() - first);
     click_chatter("%s", sa.c_str());
 }
 #endif
@@ -125,12 +120,11 @@
 LinkUnqueue::run_task()
 {
     bool worked = false;
-    struct timeval now;
-    click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
 
     // Read a new packet if there's room
     if (_signal) {
-	struct timeval now_delayed = now + _latency;
+	Timestamp now_delayed = now + _latency;
 	
 	// check for timer problems
 	if (_state == S_TIMER && _qtail
@@ -146,7 +140,7 @@
 		    delay_by_bandwidth(p, _qtail->timestamp_anno());
 		else
 		    delay_by_bandwidth(p, now_delayed);
-		//click_chatter("%{timeval}: %d GOT NEW %{timeval}", &now, _state, &_qtail->timestamp_anno());
+		//click_chatter("%{timestamp}: %d GOT NEW %{timestamp}", &now, _state, &_qtail->timestamp_anno());
 	    } else {
 		_qhead = p;
 		delay_by_bandwidth(p, now_delayed);
@@ -165,7 +159,7 @@
 	if (!_qhead)
 	    _qtail = 0;
 	p->set_next(0);
-	//click_chatter("%{timeval}: RELEASE %{timeval}", &now, &p->timestamp_anno());
+	//click_chatter("%{timestamp}: RELEASE %{timestamp}", &now, &p->timestamp_anno());
 	output(0).push(p);
 	Storage::_tail--;
 	worked = true;
@@ -174,15 +168,15 @@
     // Figure out when to schedule next
     //print_queue(_qhead);
     if (_qhead) {
-	click_gettimeofday(&now);
-	struct timeval expiry = _qhead->timestamp_anno();
+	now = Timestamp::now();
+	Timestamp expiry = _qhead->timestamp_anno();
 	if (_signal) {
-	    struct timeval expiry2 = _qtail->timestamp_anno() - _latency;
+	    Timestamp expiry2 = _qtail->timestamp_anno() - _latency;
 	    if (expiry2 < expiry)
 		expiry = expiry2;
 	}
-	//{ struct timeval diff = expiry - now; click_chatter("%{timeval}: %{timeval} > + %{timeval}", &now, &expiry, &diff); }
-	expiry -= make_timeval(0, 5000);
+	//{ Timestamp diff = expiry - now; click_chatter("%{timestamp}: %{timestamp} > + %{timestamp}", &now, &expiry, &diff); }
+	expiry -= Timestamp(0, 5000);
 	if (expiry <= now) {
 	    // small delay, reschedule Task
 	    _state = S_TASK;
Index: elements/standard/linkunqueue.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/linkunqueue.hh,v
retrieving revision 1.4
diff -u -u -w -r1.4 linkunqueue.hh
--- elements/standard/linkunqueue.hh	11 May 2004 19:18:58 -0000	1.4
+++ elements/standard/linkunqueue.hh	30 Dec 2004 23:50:33 -0000
@@ -76,14 +76,14 @@
 
     Packet *_qhead;
     Packet *_qtail;
-    struct timeval _latency;
+    Timestamp _latency;
     enum { S_TASK, S_TIMER, S_ASLEEP } _state;
     uint32_t _bandwidth;
     Task _task;
     Timer _timer;
     NotifierSignal _signal;
 
-    void delay_by_bandwidth(Packet *, const struct timeval &) const;
+    void delay_by_bandwidth(Packet *, const Timestamp &) const;
     static String read_param(Element *, void *);
     static int write_handler(const String &, Element *, void *, ErrorHandler *);
 
Index: elements/standard/randomsource.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/randomsource.cc,v
retrieving revision 1.21
diff -u -u -w -r1.21 randomsource.cc
--- elements/standard/randomsource.cc	15 Sep 2004 23:59:23 -0000	1.21
+++ elements/standard/randomsource.cc	30 Dec 2004 23:50:33 -0000
@@ -70,7 +70,7 @@
     for( ; i < _length; i++)
 	*(d + i) = random();
 
-    click_gettimeofday(&p->timestamp_anno());
+    p->timestamp_anno().set_now();
     return p;
 }
 
Index: elements/standard/ratedsource.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/ratedsource.cc,v
retrieving revision 1.50
diff -u -u -w -r1.50 ratedsource.cc
--- elements/standard/ratedsource.cc	24 Jun 2004 00:04:18 -0000	1.50
+++ elements/standard/ratedsource.cc	30 Dec 2004 23:50:33 -0000
@@ -103,8 +103,7 @@
     return false;
   }
   
-  struct timeval now;
-  click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
   if (_rate.need_update(now)) {
     _rate.update();
     Packet *p = _packet->clone();
@@ -130,8 +129,7 @@
     return 0;
   }
 
-  struct timeval now;
-  click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
   if (_rate.need_update(now)) { 
     _rate.update();
     _count++;
Index: elements/standard/ratedsplitter.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/ratedsplitter.cc,v
retrieving revision 1.20
diff -u -u -w -r1.20 ratedsplitter.cc
--- elements/standard/ratedsplitter.cc	24 Jun 2004 00:04:20 -0000	1.20
+++ elements/standard/ratedsplitter.cc	30 Dec 2004 23:50:33 -0000
@@ -55,9 +55,7 @@
 void
 RatedSplitter::push(int, Packet *p)
 {
-    struct timeval now;
-    click_gettimeofday(&now);
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
 	_rate.update();
 	output(0).push(p);
     } else
Index: elements/standard/ratedunqueue.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/ratedunqueue.cc,v
retrieving revision 1.25
diff -u -u -w -r1.25 ratedunqueue.cc
--- elements/standard/ratedunqueue.cc	24 Jun 2004 00:04:20 -0000	1.25
+++ elements/standard/ratedunqueue.cc	30 Dec 2004 23:50:33 -0000
@@ -65,10 +65,8 @@
 RatedUnqueue::run_task()
 {
 #if 1    // listening for notifications
-    struct timeval now;
-    click_gettimeofday(&now);
     bool worked = false;
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
 	//_rate.update();  // uncomment this if you want it to run periodically
 	if (Packet *p = input(0).pull()) {
 	    _rate.update();  
@@ -82,10 +80,8 @@
     return worked;
 
 #else   // no notification
-    struct timeval now;
-    click_gettimeofday(&now);
     bool worked = false;
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
 	if (Packet *p = input(0).pull()) {
 	    _rate.update();
 	    output(0).push(p);
Index: elements/standard/settimestamp.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/settimestamp.cc,v
retrieving revision 1.7
diff -u -u -w -r1.7 settimestamp.cc
--- elements/standard/settimestamp.cc	19 May 2004 01:19:45 -0000	1.7
+++ elements/standard/settimestamp.cc	30 Dec 2004 23:50:33 -0000
@@ -36,10 +36,10 @@
 int
 SetTimestamp::configure(Vector<String> &conf, ErrorHandler *errh)
 {
-    _tv.tv_sec = -1;
+    _tv._sec = -1;
     if (cp_va_parse(conf, this, errh,
 		    cpOptional,
-		    cpTimeval, "timestamp", &_tv,
+		    cpTimestamp, "timestamp", &_tv,
 		    cpEnd) < 0)
 	return -1;
     return 0;
@@ -48,11 +48,11 @@
 Packet *
 SetTimestamp::simple_action(Packet *p)
 {
-    struct timeval &tv = p->timestamp_anno();
-    if (_tv.tv_sec >= 0)
+    Timestamp& tv = p->timestamp_anno();
+    if (_tv._sec >= 0)
 	tv = _tv;
     else
-	click_gettimeofday(&tv);
+	tv.set_now();
     return p;
 }
 
Index: elements/standard/settimestamp.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/settimestamp.hh,v
retrieving revision 1.6
diff -u -u -w -r1.6 settimestamp.hh
--- elements/standard/settimestamp.hh	19 May 2004 01:19:45 -0000	1.6
+++ elements/standard/settimestamp.hh	30 Dec 2004 23:50:33 -0000
@@ -34,7 +34,7 @@
 
   private:
 
-    struct timeval _tv;
+    Timestamp _tv;
 
 };
 
Index: elements/standard/shaper.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/shaper.cc,v
retrieving revision 1.33
diff -u -u -w -r1.33 shaper.cc
--- elements/standard/shaper.cc	24 Jun 2004 00:04:20 -0000	1.33
+++ elements/standard/shaper.cc	30 Dec 2004 23:50:33 -0000
@@ -59,9 +59,7 @@
 Shaper::pull(int)
 {
     Packet *p = 0;
-    struct timeval now;
-    click_gettimeofday(&now);
-    if (_rate.need_update(now)) {
+    if (_rate.need_update(Timestamp::now())) {
 	if ((p = input(0).pull()))
 	    _rate.update();
     }
Index: elements/standard/timedsource.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/standard/timedsource.cc,v
retrieving revision 1.31
diff -u -u -w -r1.31 timedsource.cc
--- elements/standard/timedsource.cc	24 Jun 2004 00:04:20 -0000	1.31
+++ elements/standard/timedsource.cc	30 Dec 2004 23:50:33 -0000
@@ -90,7 +90,7 @@
     return;
   if (_limit < 0 || _count < _limit) {
     Packet *p = _packet->clone();
-    click_gettimeofday(&p->timestamp_anno());
+	p->timestamp_anno().set_now();
     output(0).push(p);
     _count++;
     _timer.reschedule_after_ms(_interval);
Index: elements/userlevel/fakepcap.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/fakepcap.hh,v
retrieving revision 1.19
diff -u -u -w -r1.19 fakepcap.hh
--- elements/userlevel/fakepcap.hh	3 Sep 2004 18:40:36 -0000	1.19
+++ elements/userlevel/fakepcap.hh	30 Dec 2004 23:50:33 -0000
@@ -4,8 +4,8 @@
 #include <click/packet.hh>
 CLICK_DECLS
 
-#define FAKE_PCAP_MAGIC			0xa1b2c3d4
-#define	FAKE_MODIFIED_PCAP_MAGIC	0xa1b2cd34
+#define FAKE_PCAP_MAGIC			0xA1B2C3D4
+#define	FAKE_MODIFIED_PCAP_MAGIC	0xA1B2CD34
 #define FAKE_PCAP_VERSION_MAJOR		2
 #define FAKE_PCAP_VERSION_MINOR		4
 
@@ -46,6 +46,7 @@
 struct fake_bpf_timeval {
 	int32_t tv_sec;
 	int32_t tv_usec;
+	inline static const Timestamp *make_timestamp(const fake_bpf_timeval *tv, fake_bpf_timeval *storage);
 };
 
 /*
@@ -85,6 +86,19 @@
 fake_pcap_force_ip(WritablePacket *&p, int dlt)
 {
     return fake_pcap_force_ip(reinterpret_cast<Packet *&>(p), dlt);
+}
+
+inline const Timestamp *
+fake_bpf_timeval::make_timestamp(const fake_bpf_timeval *tv, fake_bpf_timeval *ts_storage)
+{
+#if HAVE_NANOTIMESTAMP
+    ts_storage->tv_sec = tv->tv_sec;
+    ts_storage->tv_usec = Timestamp::usec_to_subsec(tv->tv_usec);
+    return reinterpret_cast<Timestamp*>(ts_storage);
+#else
+    (void) ts_storage;
+    return reinterpret_cast<const Timestamp*>(tv);
+#endif
 }
 
 CLICK_ENDDECLS
Index: elements/userlevel/fromdump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/fromdump.cc,v
retrieving revision 1.93
diff -u -u -w -r1.93 fromdump.cc
--- elements/userlevel/fromdump.cc	11 Aug 2004 03:17:43 -0000	1.93
+++ elements/userlevel/fromdump.cc	30 Dec 2004 23:50:33 -0000
@@ -77,12 +77,7 @@
 FromDump::configure(Vector<String> &conf, ErrorHandler *errh)
 {
     bool timing = false, stop = false, active = true, force_ip = false;
-    struct timeval first_time, first_time_off, last_time, last_time_off, interval;
-    timerclear(&first_time);
-    timerclear(&first_time_off);
-    timerclear(&last_time);
-    timerclear(&last_time_off);
-    timerclear(&interval);
+    Timestamp first_time, first_time_off, last_time, last_time_off, interval;
     _sampling_prob = (1 << SAMPLING_SHIFT);
 #if CLICK_NS
     bool per_node = false;
@@ -101,11 +96,11 @@
 		    "ACTIVE", cpBool, "start active?", &active,
 		    "SAMPLE", cpUnsignedReal2, "sampling probability", SAMPLING_SHIFT, &_sampling_prob,
 		    "FORCE_IP", cpBool, "emit IP packets only?", &force_ip,
-		    "START", cpTimeval, "starting time", &first_time,
-		    "START_AFTER", cpTimeval, "starting time offset", &first_time_off,
-		    "END", cpTimeval, "ending time", &last_time,
-		    "END_AFTER", cpTimeval, "ending time offset", &last_time_off,
-		    "INTERVAL", cpTimeval, "time interval", &interval,
+		    "START", cpTimestamp, "starting time", &first_time,
+		    "START_AFTER", cpTimestamp, "starting time offset", &first_time_off,
+		    "END", cpTimestamp, "ending time", &last_time,
+		    "END_AFTER", cpTimestamp, "ending time offset", &last_time_off,
+		    "INTERVAL", cpTimestamp, "time interval", &interval,
 		    "END_CALL", cpWriteHandlerCall, "write handler for ending time", &_end_h,
 #if CLICK_NS
 		    "PER_NODE", cpBool, "prepend unique node name?", &per_node,
@@ -125,24 +120,22 @@
     _have_first_time = _have_last_time = true;
     _first_time_relative = _last_time_relative = _last_time_interval = false;
     
-    if ((timerisset(&first_time) != 0) + (timerisset(&first_time_off) != 0) > 1)
+    if ((bool) first_time + (bool) first_time_off > 1)
 	return errh->error("'START' and 'START_AFTER' are mutually exclusive");
-    else if (timerisset(&first_time))
+    else if (first_time)
 	_first_time = first_time;
-    else if (timerisset(&first_time_off))
+    else if (first_time_off)
 	_first_time = first_time_off, _first_time_relative = true;
-    else {
-	timerclear(&_first_time);
+    else
 	_have_first_time = false, _first_time_relative = true;
-    }
     
-    if ((timerisset(&last_time) != 0) + (timerisset(&last_time_off) != 0) + (timerisset(&interval) != 0) > 1)
+    if ((bool) last_time + (bool) last_time_off + (bool) interval > 1)
 	return errh->error("'END', 'END_AFTER', and 'INTERVAL' are mutually exclusive");
-    else if (timerisset(&last_time))
+    else if (last_time)
 	_last_time = last_time;
-    else if (timerisset(&last_time_off))
+    else if (last_time_off)
 	_last_time = last_time_off, _last_time_relative = true;
-    else if (timerisset(&interval))
+    else if (interval)
 	_last_time = interval, _last_time_interval = true;
     else
 	_have_last_time = false;
@@ -313,19 +306,16 @@
 }
 
 void
-FromDump::prepare_times(const fake_bpf_timeval &btv)
+FromDump::prepare_times(const Timestamp &ts)
 {
     if (_first_time_relative)
-	timeradd(&btv, &_first_time, &_first_time);
+	_first_time += ts;
     if (_last_time_relative)
-	timeradd(&btv, &_last_time, &_last_time);
+	_last_time += ts;
     else if (_last_time_interval)
-	timeradd(&_first_time, &_last_time, &_last_time);
-    if (_timing) {
-	struct timeval now;
-	click_gettimeofday(&now);
-	timersub(&now, &btv, &_time_offset);
-    }
+	_last_time += _first_time;
+    if (_timing)
+	_time_offset = Timestamp::now() - ts;
     _have_any_times = true;
 }
 
@@ -334,6 +324,7 @@
 {
     fake_pcap_pkthdr swapped_ph;
     const fake_pcap_pkthdr *ph;
+    const Timestamp *ts_ptr;
     int len, caplen, skiplen = 0;
     Packet *p;
     int tries = 0;
@@ -383,16 +374,17 @@
 
     // check times
   check_times:
+    ts_ptr = fake_bpf_timeval::make_timestamp(&ph->ts, &swapped_ph.ts);
     if (!_have_any_times)
-	prepare_times(ph->ts);
+	prepare_times(*ts_ptr);
     if (_have_first_time) {
-	if (timercmp(&ph->ts, &_first_time, <)) {
+	if (*ts_ptr < _first_time) {
 	    _ff.shift_pos(caplen + skiplen);
 	    goto retry;
 	} else
 	    _have_first_time = false;
     }
-    if (_have_last_time && !timercmp(&ph->ts, &_last_time, <)) {
+    if (_have_last_time && *ts_ptr >= _last_time) {
 	_have_last_time = false;
 	(void) _end_h->call_write(errh);
 	if (!_active) {
@@ -411,7 +403,7 @@
     }
     
     // create packet
-    p = _ff.get_packet(caplen, ph->ts.tv_sec, ph->ts.tv_usec, errh);
+    p = _ff.get_packet(caplen, ts_ptr->_sec, ts_ptr->_subsec, errh);
     if (!p)
 	return false;
     SET_EXTRA_LENGTH_ANNO(p, len - caplen);
@@ -437,15 +429,11 @@
     bool more = true;
     if (!_packet)
 	more = read_packet(0);
-    if (_packet && _timing) {
-	struct timeval now;
-	click_gettimeofday(&now);
-	timersub(&now, &_time_offset, &now);
-	if (timercmp(&_packet->timestamp_anno(), &now, >)) {
+    if (_packet && _timing)
+	if (_packet->timestamp_anno() > Timestamp::now() - _time_offset) {
 	    _task.fast_reschedule();
 	    return false;
 	}
-    }
 
     if (more)
 	_task.fast_reschedule();
@@ -471,13 +459,9 @@
     bool more = true;
     if (!_packet)
 	more = read_packet(0);
-    if (_packet && _timing) {
-	struct timeval now;
-	click_gettimeofday(&now);
-	timersub(&now, &_time_offset, &now);
-	if (timercmp(&_packet->timestamp_anno(), &now, >))
+    if (_packet && _timing)
+	if (_packet->timestamp_anno() > Timestamp::now() - _time_offset)
 	    return 0;
-    }
 
     // notify presence/absence of more packets
     _notifier.set_listeners(more);
@@ -531,9 +515,9 @@
 	fd->router()->please_stop_driver();
 	return 0;
       case H_EXTEND_INTERVAL: {
-	  struct timeval tv;
-	  if (cp_timeval(s, &tv)) {
-	      timeradd(&fd->_last_time, &tv, &fd->_last_time);
+	  Timestamp ts;
+	  if (cp_time(s, &ts)) {
+	      fd->_last_time += ts;
 	      if (fd->_end_h)
 		  fd->_have_last_time = true, fd->set_active(true);
 	      return 0;
Index: elements/userlevel/fromdump.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/fromdump.hh,v
retrieving revision 1.55
diff -u -u -w -r1.55 fromdump.hh
--- elements/userlevel/fromdump.hh	29 Jul 2004 19:59:03 -0000	1.55
+++ elements/userlevel/fromdump.hh	30 Dec 2004 23:50:34 -0000
@@ -216,19 +216,19 @@
     int _minor_version;
     int _linktype;
 
-    struct timeval _first_time;
-    struct timeval _last_time;
+    Timestamp _first_time;
+    Timestamp _last_time;
     HandlerCall *_end_h;
     
     Task _task;
     ActiveNotifier _notifier;
 
-    struct timeval _time_offset;
+    Timestamp _time_offset;
     off_t _packet_filepos;
 
     bool read_packet(ErrorHandler *);
 
-    void prepare_times(const struct fake_bpf_timeval &);
+    void prepare_times(const Timestamp &);
 
     static String read_handler(Element *, void *);
     static int write_handler(const String &, Element *, void *, ErrorHandler *);
Index: elements/userlevel/fromfile.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/fromfile.cc,v
retrieving revision 1.8
diff -u -u -w -r1.8 fromfile.cc
--- elements/userlevel/fromfile.cc	11 Aug 2004 03:16:46 -0000	1.8
+++ elements/userlevel/fromfile.cc	30 Dec 2004 23:50:34 -0000
@@ -484,12 +484,12 @@
 }
 
 Packet *
-FromFile::get_packet(size_t size, uint32_t tv_sec, uint32_t tv_usec, ErrorHandler *errh)
+FromFile::get_packet(size_t size, uint32_t sec, uint32_t subsec, ErrorHandler *errh)
 {
     if (_pos + size <= _len) {
 	if (Packet *p = _data_packet->clone()) {
 	    p->shrink_data(_buffer + _pos, size);
-	    p->set_timestamp_anno(tv_sec, tv_usec);
+	    p->timestamp_anno().set(sec, subsec);
 	    _pos += size;
 	    return p;
 	}
@@ -499,7 +499,7 @@
 		p->kill();
 		return 0;
 	    } else {
-		p->set_timestamp_anno(tv_sec, tv_usec);
+		p->timestamp_anno().set(sec, subsec);
 		return p;
 	    }
 	}
@@ -509,13 +509,13 @@
 }
 
 Packet *
-FromFile::get_packet_from_data(const void *data_void, size_t data_size, size_t size, uint32_t tv_sec, uint32_t tv_usec, ErrorHandler *errh)
+FromFile::get_packet_from_data(const void *data_void, size_t data_size, size_t size, uint32_t sec, uint32_t subsec, ErrorHandler *errh)
 {
     const uint8_t *data = reinterpret_cast<const uint8_t *>(data_void);
     if (data >= _buffer && data + size <= _buffer + _len) {
 	if (Packet *p = _data_packet->clone()) {
 	    p->shrink_data(data, size);
-	    p->set_timestamp_anno(tv_sec, tv_usec);
+	    p->timestamp_anno().set(sec, subsec);
 	    return p;
 	}
     } else {
@@ -526,7 +526,7 @@
 		p->kill();
 		return 0;
 	    }
-	    p->set_timestamp_anno(tv_sec, tv_usec);
+	    p->timestamp_anno().set(sec, subsec);
 	    return p;
 	}
     }
Index: elements/userlevel/fromfile.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/fromfile.hh,v
retrieving revision 1.4
diff -u -u -w -r1.4 fromfile.hh
--- elements/userlevel/fromfile.hh	11 Aug 2004 03:16:46 -0000	1.4
+++ elements/userlevel/fromfile.hh	30 Dec 2004 23:50:34 -0000
@@ -39,8 +39,8 @@
     const uint8_t *get_unaligned(size_t, void *, ErrorHandler * = 0);
     const uint8_t *get_aligned(size_t, void *, ErrorHandler * = 0);
     String get_string(size_t, ErrorHandler * = 0);
-    Packet *get_packet(size_t, uint32_t tv_sec, uint32_t tv_usec, ErrorHandler *);
-    Packet *get_packet_from_data(const void *buf, size_t buf_size, size_t full_size, uint32_t tv_sec, uint32_t tv_usec, ErrorHandler *);
+    Packet *get_packet(size_t, uint32_t sec, uint32_t subsec, ErrorHandler *);
+    Packet *get_packet_from_data(const void *buf, size_t buf_size, size_t full_size, uint32_t sec, uint32_t subsec, ErrorHandler *);
     void shift_pos(int delta)		{ _pos += delta; }
 
     int read_line(String &, ErrorHandler *);
Index: elements/userlevel/fromhost.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/fromhost.cc,v
retrieving revision 1.4
diff -u -u -w -r1.4 fromhost.cc
--- elements/userlevel/fromhost.cc	30 Dec 2004 16:34:07 -0000	1.4
+++ elements/userlevel/fromhost.cc	30 Dec 2004 23:50:34 -0000
@@ -188,7 +188,7 @@
 	const click_ip *ip = reinterpret_cast<const click_ip *>(p->data() + sizeof(click_ether));
 	p->set_dst_ip_anno(IPAddress(ip->ip_dst));
 	p->set_ip_header(ip, ip->ip_hl << 2);
-	(void) click_gettimeofday(&p->timestamp_anno());
+	p->timestamp_anno().set_now();
 	output(0).push(p);
     } else {
 	p->kill();
Index: elements/userlevel/fromsocket.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/fromsocket.cc,v
retrieving revision 1.2
diff -u -u -w -r1.2 fromsocket.cc
--- elements/userlevel/fromsocket.cc	22 Jun 2004 16:55:17 -0000	1.2
+++ elements/userlevel/fromsocket.cc	30 Dec 2004 23:50:34 -0000
@@ -253,7 +253,7 @@
   }
 
   // set timestamp
-  click_gettimeofday(&p->timestamp_anno());
+  p->timestamp_anno().set_now();
 
   if (p->length())
     output(0).push(p);
Index: elements/userlevel/ipflowrawsockets.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/ipflowrawsockets.cc,v
retrieving revision 1.6
diff -u -u -w -r1.6 ipflowrawsockets.cc
--- elements/userlevel/ipflowrawsockets.cc	7 Jul 2004 16:06:08 -0000	1.6
+++ elements/userlevel/ipflowrawsockets.cc	30 Dec 2004 23:50:34 -0000
@@ -307,7 +307,7 @@
     assert(p);
 
     // set annotations
-    p->set_timestamp_anno(pkthdr->ts.tv_sec, pkthdr->ts.tv_usec);
+    p->timestamp_anno().set(pkthdr->ts.tv_sec, pkthdr->ts.tv_usec);
     SET_EXTRA_LENGTH_ANNO(p, pkthdr->len - length);
 }
 }
Index: elements/userlevel/kerneltap.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/kerneltap.cc,v
retrieving revision 1.42
diff -u -u -w -r1.42 kerneltap.cc
--- elements/userlevel/kerneltap.cc	26 Oct 2004 16:39:47 -0000	1.42
+++ elements/userlevel/kerneltap.cc	30 Dec 2004 23:50:34 -0000
@@ -331,7 +331,7 @@
 	    p->pull(2);
 	}
 	
-	(void) click_gettimeofday(&p->timestamp_anno());
+	p->timestamp_anno().set_now();
 	output(0).push(p);
     } else {
 	if (!_ignore_q_errs || !_printed_read_err || (errno != ENOBUFS)) {
Index: elements/userlevel/kerneltun.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/kerneltun.cc,v
retrieving revision 1.50
diff -u -u -w -r1.50 kerneltun.cc
--- elements/userlevel/kerneltun.cc	18 Nov 2004 19:58:11 -0000	1.50
+++ elements/userlevel/kerneltun.cc	30 Dec 2004 23:50:34 -0000
@@ -379,7 +379,7 @@
 	}
 
 	if (ok) {
-	    (void) click_gettimeofday(&p->timestamp_anno());
+	    p->timestamp_anno().set_now();
 	    output(0).push(p);
 	} else
 	    checked_output_push(1, p);
Index: elements/userlevel/printold.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/printold.cc,v
retrieving revision 1.10
diff -u -u -w -r1.10 printold.cc
--- elements/userlevel/printold.cc	3 May 2004 06:05:02 -0000	1.10
+++ elements/userlevel/printold.cc	30 Dec 2004 23:50:34 -0000
@@ -56,7 +56,7 @@
 Packet *
 PrintOld::simple_action(Packet *p)
 {
-  if (p->timestamp_anno().tv_sec == 0) {
+  if (p->timestamp_anno()._sec == 0) {
     click_chatter("%s: packet timestamp not set", id().cc());
     return p;
   }
@@ -67,15 +67,10 @@
     return p;
   }
 
-  struct timeval tv_now;
-  int res = gettimeofday(&tv_now, 0);
-  if (res != 0) {
-    click_chatter("%s: unable to get time of day", id().cc());
-    return p;
-  }
+  Timestamp now = Timestamp::now();
 
-  long age_s = tv_now.tv_sec - p->timestamp_anno().tv_sec;
-  long age_u = tv_now.tv_usec - p->timestamp_anno().tv_usec;
+  long age_s = tv_now._sec - p->timestamp_anno()._sec;
+  long age_u = tv_now.usec() - p->timestamp_anno().usec();
 
   // skankyness... 
   long age_ms = age_s * 1000 + age_u / 1000;
@@ -83,10 +78,8 @@
 #if 1
   assert(sizeof(long) == sizeof(int));
   if (age_ms > _thresh)
-    click_chatter("%s Now-FromDevice age is %d (FromDevice time: %ld.%06ld  dsec %ld  dusec %ld)", 
-		  id().cc(), age_ms, 
-		  p->timestamp_anno().tv_sec, p->timestamp_anno().tv_usec,
-		  age_s, age_u);
+    click_chatter("%s Now-FromDevice age is %d (FromDevice time: %{timestamp}  dsec %ld  dusec %ld)", 
+		  id().cc(), age_ms, &p->timestamp_anno(), age_s, age_u);
 #endif
 
 #if 1
@@ -136,5 +129,5 @@
 }
 
 CLICK_ENDDECLS
-ELEMENT_REQUIRES(userlevel)
+ELEMENT_REQUIRES(userlevel false)
 EXPORT_ELEMENT(PrintOld)
Index: elements/userlevel/progressbar.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/progressbar.cc,v
retrieving revision 1.26
diff -u -u -w -r1.26 progressbar.cc
--- elements/userlevel/progressbar.cc	17 Jul 2004 21:44:43 -0000	1.26
+++ elements/userlevel/progressbar.cc	30 Dec 2004 23:50:34 -0000
@@ -185,13 +185,9 @@
 	if (!_have_size)
 	    _have_size = get_value(0, _first_pos_h, &_size);
 	_last_pos = 0;
-	click_gettimeofday(&_start_time);
-	_last_time = _start_time;
-	timerclear(&_stall_time);
-	struct timeval delay;
-	delay.tv_sec = _delay_ms / 1000;
-	delay.tv_usec = (_delay_ms % 1000) * 1000;
-	timeradd(&_start_time, &delay, &_delay_time);
+	_last_time = _start_time = Timestamp::now();
+	_stall_time = Timestamp();
+	_delay_time = _start_time + Timestamp::make_msec(_delay_ms);
 	if (_status == ST_FIRST)
 	    _status = ST_MIDDLE;
     }
@@ -203,11 +199,10 @@
     }
 
     // get current time
-    struct timeval now;
-    click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
 
     // exit if wait time not passed
-    if (timercmp(&now, &_delay_time, <)) {
+    if (now < _delay_time) {
 	_timer.reschedule_at(_delay_time);
 	return;
     }
@@ -276,27 +271,23 @@
 	sa << " -----   ";
 
     // check wait time
-    struct timeval wait;
-    timersub(&now, &_last_time, &wait);
+    Timestamp wait = now - _last_time;
     if (pos > _last_pos) {
 	_last_time = now;
 	_last_pos = pos;
-	if (wait.tv_sec >= STALLTIME)
-	    timeradd(&_stall_time, &wait, &_stall_time);
-	wait.tv_sec = 0;
+	if (wait._sec >= STALLTIME)
+	    _stall_time += wait;
+	wait._sec = 0;
     }
 
     // check elapsed time
-    struct timeval tv;
-    timersub(&now, &_start_time, &tv);
-    timersub(&tv, &_stall_time, &tv);
-    double elapsed = tv.tv_sec + (tv.tv_usec / 1000000.0);
+    double elapsed = (now - _start_time - _stall_time).to_double();
 
     // collect time
     if (_status < ST_DONE
 	&& (!_have_size || elapsed <= 0.0 || pos > _size))
 	sa << "   --:-- ETA";
-    else if (wait.tv_sec >= STALLTIME)
+    else if (wait._sec >= STALLTIME)
 	sa << " - stalled -";
     else {
 	int time_remaining;
Index: elements/userlevel/progressbar.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/progressbar.hh,v
retrieving revision 1.18
diff -u -u -w -r1.18 progressbar.hh
--- elements/userlevel/progressbar.hh	17 Jul 2004 21:44:43 -0000	1.18
+++ elements/userlevel/progressbar.hh	30 Dec 2004 23:50:34 -0000
@@ -163,10 +163,10 @@
     int _status;
     double _size;
     double _last_pos;
-    struct timeval _start_time;
-    struct timeval _stall_time;
-    struct timeval _last_time;
-    struct timeval _delay_time;
+    Timestamp _start_time;
+    Timestamp _stall_time;
+    Timestamp _last_time;
+    Timestamp _delay_time;
     String _banner;
 
     Timer _timer;
Index: elements/userlevel/todevice.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/todevice.cc,v
retrieving revision 1.44
diff -u -u -w -r1.44 todevice.cc
--- elements/userlevel/todevice.cc	7 Dec 2004 06:13:29 -0000	1.44
+++ elements/userlevel/todevice.cc	30 Dec 2004 23:50:34 -0000
@@ -190,27 +190,18 @@
     
     if (retval < 0) {
       if (errno == ENOBUFS || errno == EAGAIN) {
-	struct timeval now;
-	struct timeval after;
 	assert(!_q);
 	_q = p;
 	/* we should backoff */
 	remove_select(_fd, SELECT_WRITE);
 
-	click_gettimeofday(&now);
 	_backoff = (!_backoff) ? 1 : _backoff*2;
-	after.tv_usec = _backoff % 1000000;
-	after.tv_sec = _backoff / 1000000;
-	timeradd(&now, &after, &after);
-	_timer.schedule_at(after);
+	_timer.schedule_after(Timestamp::make_usec(_backoff));
 
 	if (_debug) {
-	  StringAccum sa;
-	  sa << now;
-	  click_chatter("%{element} backing off for %d at %s\n",
-			this,
-			_backoff,
-			sa.take_string().cc());
+	    Timestamp now = Timestamp::now();
+	    click_chatter("%{element} backing off for %d at %{timestamp}\n",
+			  this, _backoff, &now);
 	}
 	return;
       } else {
Index: elements/userlevel/todump.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/userlevel/todump.cc,v
retrieving revision 1.60
diff -u -u -w -r1.60 todump.cc
--- elements/userlevel/todump.cc	13 Nov 2004 04:03:15 -0000	1.60
+++ elements/userlevel/todump.cc	30 Dec 2004 23:50:34 -0000
@@ -197,15 +197,14 @@
 {
     struct fake_pcap_pkthdr ph;
   
-    const struct timeval &ts = p->timestamp_anno();
-    if (!ts.tv_sec && !ts.tv_usec) {
-	struct timeval now;
-	click_gettimeofday(&now);
-	ph.ts.tv_sec = now.tv_sec;
-	ph.ts.tv_usec = now.tv_usec;
+    const Timestamp& ts = p->timestamp_anno();
+    if (!ts) {
+	Timestamp now = Timestamp::now();
+	ph.ts.tv_sec = now.sec();
+	ph.ts.tv_usec = now.usec();
     } else {
-	ph.ts.tv_sec = ts.tv_sec;
-	ph.ts.tv_usec = ts.tv_usec;
+	ph.ts.tv_sec = ts.sec();
+	ph.ts.tv_usec = ts.usec();
     }
 
     unsigned to_write = p->length();
Index: elements/wifi/probetxrate.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/probetxrate.cc,v
retrieving revision 1.17
diff -u -u -w -r1.17 probetxrate.cc
--- elements/wifi/probetxrate.cc	30 Dec 2004 16:49:08 -0000	1.17
+++ elements/wifi/probetxrate.cc	30 Dec 2004 23:50:34 -0000
@@ -87,8 +87,7 @@
     return errh->error("AvailableRates element is not provided or not a AvailableRates");
 
 
-  _rate_window.tv_sec = _rate_window_ms / 1000;
-  _rate_window.tv_usec = (_rate_window_ms % 1000) * 1000;
+  _rate_window = Timestamp::make_msec(_rate_window_ms);
 
   return ret;
 }
@@ -124,11 +123,7 @@
     nfo = _neighbors.findp(dst);
   }
 
-  struct timeval now;
-  struct timeval old;
-  click_gettimeofday(&now);
-  timersub(&now, &_rate_window, &old);
-  nfo->trim(old);
+  nfo->trim(Timestamp::now() - _rate_window);
   //nfo->check();
 
   int best_ndx = nfo->best_rate_ndx();
@@ -178,8 +173,7 @@
   int retries = _alt_rate ? MIN(_original_retries, ceh->retries) :
     ceh->retries;
 
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
 
   if (dst == _bcast) {
     /* don't record info for bcast packets */
Index: elements/wifi/probetxrate.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/probetxrate.hh,v
retrieving revision 1.16
diff -u -u -w -r1.16 probetxrate.hh
--- elements/wifi/probetxrate.hh	30 Dec 2004 16:49:08 -0000	1.16
+++ elements/wifi/probetxrate.hh	30 Dec 2004 23:50:34 -0000
@@ -80,12 +80,12 @@
   String print_rates();
 
   struct tx_result {
-    struct timeval _when;
+    Timestamp _when;
     int _rate;
     bool _success;
     int _time;
     
-    tx_result(const struct timeval &t, int rate, 
+    tx_result(const Timestamp &t, int rate, 
 	      bool success, int time) : 
       _when(t), 
       _rate(rate), 
@@ -177,7 +177,7 @@
       }
     }
 
-    void add_result(struct timeval now, int rate, int success,
+    void add_result(const Timestamp &now, int rate, int success,
 		    int time) {
       int ndx = rate_index(rate);
       if (!rate || ndx < 0 || ndx > _rates.size()){
@@ -195,9 +195,9 @@
 
 
 
-    void trim(struct timeval t) {
+    void trim(const Timestamp &ts) {
       int trimmed = 0;
-      while (_results.size() && timercmp(&_results[0]._when, &t, <)) {
+      while (_results.size() && _results[0]._when < ts) {
 	trimmed++;
 	tx_result t = _results[0];
 	_results.pop_front();
@@ -292,7 +292,7 @@
   NeighborTable _neighbors;
   EtherAddress _bcast;
   int _rate_window_ms;
-  struct timeval _rate_window;
+  Timestamp _rate_window;
 
   AvailableRates *_rtable;
   bool _filter_low_rates;
Index: elements/wifi/txflog.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/txflog.hh,v
retrieving revision 1.1
diff -u -u -w -r1.1 txflog.hh
--- elements/wifi/txflog.hh	7 Dec 2004 08:33:42 -0000	1.1
+++ elements/wifi/txflog.hh	30 Dec 2004 23:50:34 -0000
@@ -48,7 +48,7 @@
 
   
   DEQueue<struct click_wifi_extra> _p;
-  DEQueue<struct timeval> _t;
+  DEQueue<Timestamp> _t;
 
 };
 
Index: elements/wifi/sr/counterflood.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/counterflood.cc,v
retrieving revision 1.3
diff -u -u -w -r1.3 counterflood.cc
--- elements/wifi/sr/counterflood.cc	27 Sep 2004 22:02:32 -0000	1.3
+++ elements/wifi/sr/counterflood.cc	30 Dec 2004 23:50:34 -0000
@@ -166,10 +166,9 @@
 void
 CounterFlood::forward_hook() 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
   for (int x = 0; x < _packets.size(); x++) {
-    if (timercmp(&now, &_packets[x]._to_send, >)) {
+    if (now > _packets[x]._to_send) {
       /* this timer has expired */
       if (!_packets[x]._forwarded && 
 	  (!_count || _packets[x]._num_rx < _count)) {
@@ -204,8 +203,7 @@
 void
 CounterFlood::push(int port, Packet *p_in)
 {
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
   
   if (port == 1) {
     _packets_originated++;
@@ -266,10 +264,7 @@
       int delay_time = (random() % _max_delay_ms) + 1;
       sr_assert(delay_time > 0);
       
-      struct timeval delay;
-      delay.tv_sec = 0;
-      delay.tv_usec = delay_time*1000;
-      timeradd(&now, &delay, &_packets[index]._to_send);
+      _packets[index]._to_send = now + Timestamp::make_msec(delay_time);
       _packets[index].t = new Timer(static_forward_hook, (void *) this);
       _packets[index].t->initialize(this);
       _packets[index].t->schedule_at(_packets[index]._to_send);
Index: elements/wifi/sr/counterflood.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/counterflood.hh,v
retrieving revision 1.2
diff -u -u -w -r1.2 counterflood.hh
--- elements/wifi/sr/counterflood.hh	3 Dec 2004 21:17:03 -0000	1.2
+++ elements/wifi/sr/counterflood.hh	30 Dec 2004 23:50:34 -0000
@@ -81,11 +81,11 @@
     bool _originated; /* this node started the bcast */
     Packet *_p;
     int _num_rx;
-    struct timeval _first_rx;
+    Timestamp _first_rx;
     bool _forwarded;
     bool _actually_sent;
     Timer *t;
-    struct timeval _to_send;
+    Timestamp _to_send;
     Vector<IPAddress> _rx_from;
     Vector<uint32_t> _rx_from_seq;
     Vector<uint32_t> _sent_seq;
Index: elements/wifi/sr/ettstat.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/ettstat.cc,v
retrieving revision 1.16
diff -u -u -w -r1.16 ettstat.cc
--- elements/wifi/sr/ettstat.cc	7 Dec 2004 08:33:43 -0000	1.16
+++ elements/wifi/sr/ettstat.cc	30 Dec 2004 23:50:34 -0000
@@ -234,10 +234,7 @@
   _sent = q->_sent;
   _start = q->_start;
 
-  struct timeval now;
-  click_gettimeofday(&now);
-
-  if (timercmp(&now, &q->_next, <)) {
+  if (Timestamp::now() < q->_next) {
     _timer->unschedule();
     _timer->schedule_at(q->_next);
     _next = q->_next;
@@ -246,18 +243,12 @@
   
 }
 
-void add_jitter(unsigned int max_jitter, struct timeval *t) {
-  struct timeval jitter;
+void add_jitter(unsigned int max_jitter, Timestamp *t) {
   unsigned j = (unsigned) (random() % (max_jitter + 1));
-  unsigned int delta_us = 1000 * j;
-  timerclear(&jitter);
-  jitter.tv_usec += delta_us;
-  jitter.tv_sec +=  jitter.tv_usec / 1000000;
-  jitter.tv_usec = (jitter.tv_usec % 1000000);
   if (random() & 1) {
-    timeradd(t, &jitter, t);
+      *t += Timestamp::make_msec(j);
   } else {
-    timersub(t, &jitter, t);
+      *t -= Timestamp::make_msec(j);
   }
   return;
 }
@@ -288,15 +279,7 @@
 
   send_probe();
   
-
-  struct timeval period;
-  timerclear(&period);
-
-  period.tv_usec += (p * 1000);
-  period.tv_sec += period.tv_usec / 1000000;
-  period.tv_usec = (period.tv_usec % 1000000);
-
-  timeradd(&period, &_next, &_next);
+  _next += Timestamp::make_msec(p);
   add_jitter(max_jitter, &_next);
   _timer->schedule_at(_next);
 }
@@ -337,9 +320,7 @@
   p->pull(2);
   memset(p->data(), 0, p->length());
 
-  struct timeval now;
-  click_gettimeofday(&now);
-  p->set_timestamp_anno(now);
+  p->set_timestamp_anno(Timestamp::now());
   
   // fill in ethernet header 
   click_ether *eh = (click_ether *) p->data();
@@ -350,7 +331,7 @@
   link_probe *lp = (struct link_probe *) (p->data() + sizeof(click_ether));
   lp->_version = _ett_version;
   lp->_ip = _ip.addr();
-  lp->_seq = now.tv_sec;
+  lp->_seq = p->timestamp_anno().sec();
   lp->_period = _period;
   lp->_tau = _tau;
   lp->_sent = _sent;
@@ -456,10 +437,8 @@
 
     _stale_timer.initialize(this);
     _stale_timer.schedule_now();
-    struct timeval now;
-    click_gettimeofday(&now);
     
-    _next = now;
+    _next = Timestamp::now();
 
     unsigned max_jitter = _period / 10;
     add_jitter(max_jitter, &_next);
@@ -478,8 +457,7 @@
 {
 
   
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
 
   unsigned min_sz = sizeof(click_ether) + sizeof(link_probe);
   if (p->length() < min_sz) {
@@ -588,7 +566,7 @@
 
   /* keep stats for at least the averaging period */
   while ((unsigned) l->_probes.size() &&
-	 now.tv_sec - l->_probes[0]._when.tv_sec > (signed) (1 + (l->_tau / 1000)))
+	 now._sec - l->_probes[0]._when._sec > (signed) (1 + (l->_tau / 1000)))
     l->_probes.pop_front();
   
 
@@ -681,7 +659,7 @@
     int seq = entry->_seq;
     if (neighbor == ip && 
 	((uint32_t) neighbor > (uint32_t) _ip)) {
-      seq = now.tv_sec;
+      seq = now._sec;
     }
     update_link(ip, neighbor, rates, fwd, rev, seq);
     ptr += num_rates * sizeof(struct link_info);
@@ -721,8 +699,7 @@
   for (ProbeMap::const_iterator i = _bcast_stats.begin(); i; i++) 
     ip_addrs.push_back(i.key());
 
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
 
   StringAccum sa;
 
@@ -785,16 +762,15 @@
 {
   Vector<IPAddress> new_neighbors;
 
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
   for (int x = 0; x < _neighbors.size(); x++) {
     IPAddress n = _neighbors[x];
     probe_list_t *l = _bcast_stats.findp(n);
     if (!l || 
-	(unsigned) now.tv_sec - l->_last_rx.tv_sec > 2 * l->_tau/1000) {
+	(unsigned) now._sec - l->_last_rx._sec > 2 * l->_tau/1000) {
       click_chatter("%{element} clearing stale neighbor %s age %d\n ",
 		    this, n.s().cc(),
-		    now.tv_sec - l->_last_rx.tv_sec);
+		    now._sec - l->_last_rx._sec);
       _bcast_stats.remove(n);
     } else {
       new_neighbors.push_back(n);
@@ -815,7 +791,7 @@
   _rev_arp.clear();
   _seq = 0;
   _sent = 0;
-  click_gettimeofday(&_start);
+  _start = Timestamp::now();
 }
 
 
Index: elements/wifi/sr/ettstat.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/ettstat.hh,v
retrieving revision 1.12
diff -u -u -w -r1.12 ettstat.hh
--- elements/wifi/sr/ettstat.hh	30 Dec 2004 06:13:53 -0000	1.12
+++ elements/wifi/sr/ettstat.hh	30 Dec 2004 23:50:34 -0000
@@ -143,14 +143,14 @@
   class ARPTable *_arp_table;
   uint16_t _et;     // This protocol's ethertype
 
-  struct timeval _start;
+  Timestamp _start;
   // record probes received from other hosts
   struct probe_t {
-    struct timeval _when;  
+    Timestamp _when;  
     uint32_t   _seq;
     uint8_t _rate;
     uint16_t _size;
-    probe_t(const struct timeval &t, 
+    probe_t(const Timestamp &t, 
 	    uint32_t s,
 	    uint8_t r,
 	    uint16_t sz) : _when(t), _seq(s), _rate(r), _size(sz) { }
@@ -168,7 +168,7 @@
     
     Vector<int> _fwd_rates;
     
-    struct timeval _last_rx;
+    Timestamp _last_rx;
     DEQueue<probe_t> _probes;   // most recently received probes
     probe_list_t(const IPAddress &p, unsigned int per, unsigned int t) : 
       _ip(p), 
@@ -178,13 +178,9 @@
     { }
     probe_list_t() : _period(0), _tau(0) { }
 
-    int rev_rate(struct timeval start, int rate, int size) {
-      struct timeval now;
-      struct timeval p = { _tau / 1000, 1000 * (_tau % 1000) };
-      struct timeval earliest;
-      click_gettimeofday(&now);
-      timersub(&now, &p, &earliest);
-
+    int rev_rate(const Timestamp &start, int rate, int size) {
+      Timestamp now = Timestamp::now();
+      Timestamp earliest = now - Timestamp::make_msec(_tau);
 
       if (_period == 0) {
 	click_chatter("period is 0\n");
@@ -192,7 +188,7 @@
       }
       int num = 0;
       for (int i = _probes.size() - 1; i >= 0; i--) {
-	if (timercmp(&earliest, &(_probes[i]._when), >)) {
+	if (earliest > _probes[i]._when) {
 	  break;
 	} 
 	if ( _probes[i]._size == size &&
@@ -201,10 +197,9 @@
 	}
       }
       
-      struct timeval since_start;
-      timersub(&now, &start, &since_start);
+      Timestamp since_start = now - start;
 
-      uint32_t ms_since_start = MAX(0, since_start.tv_sec * 1000 + since_start.tv_usec / 1000);
+      uint32_t ms_since_start = MAX(0, since_start.msec1());
       uint32_t fake_tau = MIN(_tau, ms_since_start);
       assert(_probe_types.size());
       int num_expected = fake_tau / _period;
@@ -244,7 +239,7 @@
   Timer _stale_timer;
 
   void run_timer();
-  struct timeval _next;
+  Timestamp _next;
 
   Vector <RateSize> _ads_rs;
   int _ads_rs_index;
Index: elements/wifi/sr/flashflood.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/flashflood.cc,v
retrieving revision 1.7
diff -u -u -w -r1.7 flashflood.cc
--- elements/wifi/sr/flashflood.cc	8 Oct 2004 00:42:12 -0000	1.7
+++ elements/wifi/sr/flashflood.cc	30 Dec 2004 23:50:34 -0000
@@ -323,10 +323,9 @@
 void
 FlashFlood::forward_hook() 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
   for (int x = 0; x < _packets.size(); x++) {
-    if (timercmp(&_packets[x]._to_send, &now, <=)) {
+	if (_packets[x]._to_send <= now) {
       /* this timer has expired */
       if (!_packets[x]._sent && _packets[x]._scheduled) {
 	/* we haven't sent this packet yet */
@@ -381,8 +380,6 @@
 void 
 FlashFlood::start_flood(Packet *p_in) 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
   _packets_originated++;
   /* from me */
   int seq = random();
@@ -399,12 +396,12 @@
   _packets[bcast_index]._p = p_in;
   _packets[bcast_index]._num_rx = 0;
   _packets[bcast_index]._num_tx = 0;
-  _packets[bcast_index]._first_rx = now;
+  _packets[bcast_index]._first_rx = Timestamp::now();
   _packets[bcast_index]._actual_first_rx = true;
   _packets[bcast_index]._sent = false;
   _packets[bcast_index]._scheduled = false;
   _packets[bcast_index].t = NULL;
-  _packets[bcast_index]._to_send = now;
+  _packets[bcast_index]._to_send = _packets[bcast_index]._first_rx;
   forward(&_packets[bcast_index]);
   
 }
@@ -415,12 +412,11 @@
 
     click_ether *eh = (click_ether *) p_in->data();
     struct srpacket *pk = (struct srpacket *) (eh+1);
-    struct timeval now;
     uint32_t seq = pk->seq();
     uint32_t link_seq = pk->seq2();
     IPAddress src = pk->get_link_node(pk->num_links() - 1);
 
-    click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
 
     int map_index = -1;
     for (int x = 0; x < _mappings.size(); x++) {
@@ -481,10 +477,7 @@
       _packets[bcast_index].t->initialize(this);
       
       int delay_ms = max(get_wait_time(seq, src), 1);
-      struct timeval delay;
-      delay.tv_sec = 0;
-      delay.tv_usec = delay_ms*1000;
-      timeradd(&now, &delay, &_packets[bcast_index]._to_send);
+      _packets[bcast_index]._to_send = now + Timestamp::make_msec(delay_ms);
       
       /* schedule timer */
       _packets[bcast_index].t->schedule_at(_packets[bcast_index]._to_send);
Index: elements/wifi/sr/flashflood.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/flashflood.hh,v
retrieving revision 1.2
diff -u -u -w -r1.2 flashflood.hh
--- elements/wifi/sr/flashflood.hh	3 Dec 2004 21:17:03 -0000	1.2
+++ elements/wifi/sr/flashflood.hh	30 Dec 2004 23:50:34 -0000
@@ -100,12 +100,12 @@
     Packet *_p;
     int _num_rx;
     int _num_tx;
-    struct timeval _first_rx;
+    Timestamp _first_rx;
     bool _actual_first_rx;
     bool _scheduled;
     bool _sent;
     Timer *t;
-    struct timeval _to_send;
+    Timestamp _to_send;
     
     Vector<IPAddress> _rx_from; /* who I got this packet from */
     Vector<uint32_t> _rx_from_seq;
Index: elements/wifi/sr/gatewayselector.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/gatewayselector.cc,v
retrieving revision 1.7
diff -u -u -w -r1.7 gatewayselector.cc
--- elements/wifi/sr/gatewayselector.cc	5 Oct 2004 18:55:33 -0000	1.7
+++ elements/wifi/sr/gatewayselector.cc	30 Dec 2004 23:50:34 -0000
@@ -88,11 +88,8 @@
   if (_arp_table && _arp_table->cast("ARPTable") == 0) 
     return errh->error("ARPTable element is not an ARPtable");
 
-  _gw_expire.tv_usec = 0;
-  _gw_expire.tv_sec = _period*4;
-
-  struct timeval now;
-  click_gettimeofday(&now);
+  _gw_expire._subsec = 0;
+  _gw_expire._sec = _period*4;
 
   return ret;
 }
@@ -112,17 +109,12 @@
   if (_is_gw) {
     start_ad();
   }
-  struct timeval _next_ad;
-  click_gettimeofday(&_next_ad);
   unsigned p = _period * 1000;
   unsigned max_jitter = p / 7;
   long r2 = random();
   unsigned j = (unsigned) ((r2 >> 1) % (max_jitter + 1));
   unsigned int delta_us = 1000 * ((r2 & 1) ? p - j : p + j);
-  _next_ad.tv_usec += delta_us;
-  _next_ad.tv_sec +=  _next_ad.tv_usec / 1000000;
-  _next_ad.tv_usec = (_next_ad.tv_usec % 1000000);
-  _timer.schedule_at(_next_ad);
+  _timer.schedule_at(Timestamp::now() + Timestamp::make_usec(delta_us));
 }
 
 void
@@ -177,10 +169,9 @@
 void
 GatewaySelector::forward_ad_hook() 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
   for (int x = 0; x < _seen.size(); x++) {
-    if (timercmp(&_seen[x]._to_send, &now, <) && !_seen[x]._forwarded) {
+	if (_seen[x]._to_send < now && !_seen[x]._forwarded) {
       forward_ad(&_seen[x]);
     }
   }
@@ -243,18 +234,16 @@
 {
   IPAddress best_gw = IPAddress();
   int best_metric = 0;
-  struct timeval expire;
-  struct timeval now;
+  Timestamp now = Timestamp::now();
   
   _link_table->dijkstra(false);
-  click_gettimeofday(&now);
   
   for(GWIter iter = _gateways.begin(); iter; iter++) {
     GWInfo nfo = iter.value();
-    timeradd(&nfo._last_update, &_gw_expire, &expire);
+    Timestamp expire = nfo._last_update + _gw_expire;
     Path p = _link_table->best_route(nfo._ip, false);
     int metric = _link_table->get_route_metric(p);
-    if (timercmp(&now, &expire, <) && 
+    if (now < expire &&
 	metric && 
 	((!best_metric) || best_metric > metric) &&
 	!_ignore.findp(nfo._ip) &&
@@ -274,12 +263,7 @@
     return false;
   }
   GWInfo *nfo = _gateways.findp(gw);
-  struct timeval now;
-  struct timeval expire;
-  click_gettimeofday(&now);
-  
-  timeradd(&nfo->_last_update, &_gw_expire, &expire);
-  return timercmp(&now, &expire, <);
+  return Timestamp::now() < (nfo->_last_update + _gw_expire);
 
 }
 
@@ -368,7 +352,7 @@
     nfo = _gateways.findp(gw);
   }
   nfo->_ip = gw;
-  click_gettimeofday(&nfo->_last_update);
+  nfo->_last_update = Timestamp::now();
 
   if (_is_gw) {
     p_in->kill();
@@ -399,10 +383,7 @@
   int delay_time = (random() % 2000) + 1;
   sr_assert(delay_time > 0);
   
-  struct timeval delay;
-  delay.tv_sec = 0;
-  delay.tv_usec = delay_time*1000;
-  timeradd(&_seen[si]._when, &delay, &_seen[si]._to_send);
+  _seen[si]._to_send = _seen[si]._when + Timestamp::make_msec(delay_time);
   _seen[si]._forwarded = false;
   Timer *t = new Timer(static_forward_ad_hook, (void *) this);
   t->initialize(this);
@@ -419,8 +400,7 @@
 GatewaySelector::print_gateway_stats()
 {
     StringAccum sa;
-    struct timeval now;
-    click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
     for(GWIter iter = _gateways.begin(); iter; iter++) {
       GWInfo nfo = iter.value();
       sa << nfo._ip.s().cc() << " ";
Index: elements/wifi/sr/gatewayselector.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/gatewayselector.hh,v
retrieving revision 1.5
diff -u -u -w -r1.5 gatewayselector.hh
--- elements/wifi/sr/gatewayselector.hh	3 Dec 2004 21:17:03 -0000	1.5
+++ elements/wifi/sr/gatewayselector.hh	30 Dec 2004 23:50:34 -0000
@@ -76,10 +76,11 @@
     IPAddress _gw;
     u_long _seq;
     int _count;
-    struct timeval _when; /* when we saw the first query */
-    struct timeval _to_send;
+    Timestamp _when; /* when we saw the first query */
+    Timestamp _to_send;
     bool _forwarded;
     Seen(IPAddress gw, u_long seq, int fwd, int rev) {
+	(void) fwd, (void) rev;
       _gw = gw; 
       _seq = seq; 
       _count = 0;
@@ -99,7 +100,7 @@
   class GWInfo {
   public:
     IPAddress _ip;
-    struct timeval _last_update;
+    Timestamp _last_update;
     GWInfo() {memset(this,0,sizeof(*this)); }
   };
 
@@ -110,7 +111,7 @@
 
   int MaxSeen;   // Max size of table of already-seen queries.
   int MaxHops;   // Max hop count for queries.
-  struct timeval _gw_expire;
+  Timestamp _gw_expire;
   u_long _seq;      // Next query sequence number to use.
   IPAddress _ip;    // My IP address.
   EtherAddress _en; // My ethernet address.
Index: elements/wifi/sr/inorderqueue.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/inorderqueue.cc,v
retrieving revision 1.2
diff -u -u -w -r1.2 inorderqueue.cc
--- elements/wifi/sr/inorderqueue.cc	24 Jun 2004 00:04:45 -0000	1.2
+++ elements/wifi/sr/inorderqueue.cc	30 Dec 2004 23:50:34 -0000
@@ -130,24 +130,22 @@
     if (seq == nfo->_seq + 1) {
 	/* this is the normal case */
 	nfo->_seq = max(nfo->_seq, seq);
-	click_gettimeofday(&nfo->_last_tx);
+	nfo->_last_tx = Timestamp::now();
 	return true;
     }
 
     if (!seq || !nfo->_seq) {
 	/* reset on either end*/
 	if (_debug && nfo->_seq) {
-	    struct timeval now;
-	    click_gettimeofday(&now);
 	    StringAccum sa;
-	    sa << id() << " " << now;
+	    sa << id() << " " << Timestamp::now();
 	    sa << " reset [" << path_to_string(nfo->_p) << "]";
 	    sa << " nfo_seq " << nfo->_seq;
 	    sa << " pk_seq " << seq;
 	    click_chatter("%s", sa.take_string().cc());
 	}
 	nfo->_seq = seq;
-	click_gettimeofday(&nfo->_last_tx);
+	nfo->_last_tx = Timestamp::now();
 	return true;
     }
     
@@ -177,12 +175,12 @@
 	    click_chatter("%s", sa.take_string().cc());
 	}
 	nfo->_seq = max(nfo->_seq, seq);
-	click_gettimeofday(&nfo->_last_tx);
+	nfo->_last_tx = Timestamp::now();
 	return true;
     }
 
-    struct timeval age = nfo->last_tx_age();
-    if (timercmp(&age, &_packet_timeout, >)) {
+    Timestamp age = nfo->last_tx_age();
+    if (age > _packet_timeout) {
 	if (_debug) {
 	    struct timeval now;
 	    click_gettimeofday(&now);
@@ -195,7 +193,7 @@
 	    click_chatter("%s", sa.take_string().cc());
 	}
 	nfo->_seq = seq;
-	click_gettimeofday(&nfo->_last_tx);
+	nfo->_last_tx = Timestamp::now();
 	return true;
     }
 
@@ -314,7 +312,7 @@
   click_gettimeofday(&now);
   for(PathIter iter = _paths.begin(); iter; iter++) {
       PathInfo f = iter.value();
-      struct timeval age = f.last_tx_age();
+      Timestamp age = f.last_tx_age();
       sa << path_to_string(f._p) << " seq " << f._seq << " age " << age << "\n";
   }
 
@@ -398,8 +396,7 @@
     return errh->error("PACKET_TIMEOUT must not be 0");
   }
   _max_tx_packet_ms = x;
-  _packet_timeout.tv_sec = x/1000;
-  _packet_timeout.tv_usec = (x % 1000) * 1000;
+  _packet_timeout = Timestamp::make_msec(x);
   return 0;
 }
 
Index: elements/wifi/sr/inorderqueue.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/inorderqueue.hh,v
retrieving revision 1.1
diff -u -u -w -r1.1 inorderqueue.hh
--- elements/wifi/sr/inorderqueue.hh	27 May 2004 16:13:43 -0000	1.1
+++ elements/wifi/sr/inorderqueue.hh	30 Dec 2004 23:50:34 -0000
@@ -39,17 +39,13 @@
     public:
 	Path _p;
 	uint32_t _seq;
-	struct timeval _last_tx;
+	Timestamp _last_tx;
 
 	PathInfo() : _p(), _seq(0) { }
 	PathInfo(Path p) : _p(p), _seq(0) { }
 
-	struct timeval last_tx_age() {
-	    struct timeval age;
-	    struct timeval now;
-	    click_gettimeofday(&now);
-	    timersub(&now, &_last_tx, &age);
-	    return age;
+	Timestamp last_tx_age() {
+	    return Timestamp::now() - _last_tx;
 	}
     };
     
@@ -90,7 +86,7 @@
     
     bool _debug;
     unsigned int _max_tx_packet_ms;
-    struct timeval _packet_timeout;
+    Timestamp _packet_timeout;
     Timer _timer;
 };
 
Index: elements/wifi/sr/metricflood.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/metricflood.cc,v
retrieving revision 1.2
diff -u -u -w -r1.2 metricflood.cc
--- elements/wifi/sr/metricflood.cc	30 Dec 2004 16:49:08 -0000	1.2
+++ elements/wifi/sr/metricflood.cc	30 Dec 2004 23:50:34 -0000
@@ -133,10 +133,9 @@
 void
 MetricFlood::forward_query_hook() 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
   for (int x = 0; x < _seen.size(); x++) {
-    if (timercmp(&_seen[x]._to_send, &now, <) && !_seen[x]._forwarded) {
+    if (_seen[x]._to_send < now && !_seen[x]._forwarded) {
       forward_query(&_seen[x]);
     }
   }
@@ -156,10 +155,8 @@
   }
 
   if (0) {
-    struct timeval now;
-    click_gettimeofday(&now);
     StringAccum sa;
-    sa << now - s->_when;
+    sa << Timestamp::now() - s->_when;
     click_chatter("%{element} :: %s :: waited %s\n",
 		  this,
 		  __func__,
@@ -365,17 +362,14 @@
   si = _seen.size() - 1;
   
   _seen[si]._count++;
-  click_gettimeofday(&_seen[si]._when);
+  _seen[si]._when = Timestamp::now();
   _seen[si]._p = p_in->clone();
   
   /* schedule timer */
   int delay_time = random() % 1750 + 1;
   sr_assert(delay_time > 0);
   
-  struct timeval delay;
-  delay.tv_sec = 0;
-  delay.tv_usec = delay_time*1000;
-  timeradd(&_seen[si]._when, &delay, &_seen[si]._to_send);
+  _seen[si]._to_send = _seen[si]._when + Timestamp::make_msec(delay_time);
   _seen[si]._forwarded = false;
   Timer *t = new Timer(static_forward_query_hook, (void *) this);
   t->initialize(this);
Index: elements/wifi/sr/metricflood.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/metricflood.hh,v
retrieving revision 1.2
diff -u -u -w -r1.2 metricflood.hh
--- elements/wifi/sr/metricflood.hh	3 Dec 2004 21:17:03 -0000	1.2
+++ elements/wifi/sr/metricflood.hh	30 Dec 2004 23:50:34 -0000
@@ -61,8 +61,8 @@
     u_long _seq;
     Packet *_p;
     int _count;
-    struct timeval _when; /* when we saw the first query */
-    struct timeval _to_send;
+    Timestamp _when; /* when we saw the first query */
+    Timestamp _to_send;
     bool _forwarded;
 
 
Index: elements/wifi/sr/pflood.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/pflood.cc,v
retrieving revision 1.3
diff -u -u -w -r1.3 pflood.cc
--- elements/wifi/sr/pflood.cc	27 Sep 2004 22:02:34 -0000	1.3
+++ elements/wifi/sr/pflood.cc	30 Dec 2004 23:50:34 -0000
@@ -144,10 +144,9 @@
 void
 PFlood::forward_hook() 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
   for (int x = 0; x < _packets.size(); x++) {
-    if (timercmp(&_packets[x]._to_send, &now, <=)) {
+    if (_packets[x]._to_send <= now) {
       /* this timer has expired */
       if (!_packets[x]._forwarded) {
 	/* we haven't forwarded this packet yet */
@@ -181,8 +180,7 @@
 void
 PFlood::push(int port, Packet *p_in)
 {
-  struct timeval now;
-  click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
   
   if (port == 1) {
     _packets_originated++;
@@ -232,13 +230,9 @@
       int delay_time = (random() % _max_delay_ms) + 1;
       sr_assert(delay_time > 0);
       
-      struct timeval delay;
-      delay.tv_sec = 0;
-      delay.tv_usec = delay_time*1000;
-      timeradd(&now, &delay, &_packets[index]._to_send);
       _packets[index].t = new Timer(static_forward_hook, (void *) this);
       _packets[index].t->initialize(this);
-      _packets[index].t->schedule_at(_packets[index]._to_send);
+      _packets[index].t->schedule_at(now + Timestamp::make_msec(delay_time));
 
       /* finally, clone the packet and push it out */
       Packet *p_out = p_in->clone();
Index: elements/wifi/sr/pflood.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/pflood.hh,v
retrieving revision 1.1
diff -u -u -w -r1.1 pflood.hh
--- elements/wifi/sr/pflood.hh	27 May 2004 16:13:43 -0000	1.1
+++ elements/wifi/sr/pflood.hh	30 Dec 2004 23:50:34 -0000
@@ -88,11 +88,11 @@
     bool _originated; /* this node started the bcast */
     Packet *_p;
     int _num_rx;
-    struct timeval _first_rx;
+    Timestamp _first_rx;
     bool _forwarded;
     bool _actually_sent;
     Timer *t;
-    struct timeval _to_send;
+    Timestamp _to_send;
 
     void del_timer() {
       if (t) {
Index: elements/wifi/sr/setgateway.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/setgateway.cc,v
retrieving revision 1.2
diff -u -u -w -r1.2 setgateway.cc
--- elements/wifi/sr/setgateway.cc	24 Jun 2004 00:04:45 -0000	1.2
+++ elements/wifi/sr/setgateway.cc	30 Dec 2004 23:50:34 -0000
@@ -240,14 +240,11 @@
 void 
 SetGateway::cleanup() {
   FlowTable new_table;
-  struct timeval timeout;
-  timeout.tv_sec = 1*60;
-  timeout.tv_usec = 0;
+  Timestamp timeout(60, 0);
 
   for(FTIter i = _flow_table.begin(); i; i++) {
     FlowTableEntry f = i.value();
-    struct timeval age = f.age();
-    if (timercmp(&age, &timeout, <)) {
+    if (f.age() < timeout) {
       new_table.insert(f._id, f);
     }
   }
@@ -271,8 +268,7 @@
   click_gettimeofday(&now);
   for(FTIter iter = _flow_table.begin(); iter; iter++) {
     FlowTableEntry f = iter.value();
-    struct timeval age = f.age();
-    sa << f._id << " gw " << f._gw << " age " << age << "\n";
+    sa << f._id << " gw " << f._gw << " age " << f.age() << "\n";
   }
 
   return sa.take_string();
Index: elements/wifi/sr/setgateway.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/setgateway.hh,v
retrieving revision 1.4
diff -u -u -w -r1.4 setgateway.hh
--- elements/wifi/sr/setgateway.hh	30 Dec 2004 16:49:08 -0000	1.4
+++ elements/wifi/sr/setgateway.hh	30 Dec 2004 23:50:34 -0000
@@ -60,8 +60,8 @@
   public:
     class IPFlowID _id;
     IPAddress _gw;
-    struct timeval _oldest_unanswered;
-    struct timeval _last_reply;
+    Timestamp _oldest_unanswered;
+    Timestamp _last_reply;
     int _outstanding_syns;
     bool _fwd_alive;
     bool _rev_alive;
@@ -83,26 +83,21 @@
 
     void saw_forward_packet() {
       if (_all_answered) {
-	click_gettimeofday(&_oldest_unanswered);
+	  _oldest_unanswered = Timestamp::now();
 	_all_answered = false;
       }
     }
     void saw_reply_packet() {
-      click_gettimeofday(&_last_reply);
+      _last_reply = Timestamp::now();
       _all_answered = true;
     }
     bool is_pending() const    { return (_outstanding_syns > 0);}
 
-    struct timeval age() {
-      struct timeval age;
-      struct timeval now;
-      timerclear(&age);
-      if (_fwd_alive || _rev_alive) {
-	return age;
-      }
-      click_gettimeofday(&now);
-      timersub(&now, &_last_reply, &age);
-      return age;
+    Timestamp age() {
+      if (_fwd_alive || _rev_alive)
+	  return Timestamp();
+      else
+	  return Timestamp::now() - _last_reply;
     }
   };
 
Index: elements/wifi/sr/srquerier.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/srquerier.cc,v
retrieving revision 1.8
diff -u -u -w -r1.8 srquerier.cc
--- elements/wifi/sr/srquerier.cc	30 Dec 2004 16:49:09 -0000	1.8
+++ elements/wifi/sr/srquerier.cc	30 Dec 2004 23:50:35 -0000
@@ -43,8 +43,7 @@
   click_gettimeofday(&tv);
   _seq = tv.tv_usec;
 
-  _query_wait.tv_sec = 5;
-  _query_wait.tv_usec = 0;
+  _query_wait = Timestamp(5, 0);
 
   static unsigned char bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
   _bcast = EtherAddress(bcast_addr);
@@ -147,30 +146,23 @@
   if (best_valid) {
     if (!q->_p.size()) {
       q->_p = best;
-      click_gettimeofday(&q->_last_switch);
-      click_gettimeofday(&q->_first_selected);
+      q->_last_switch = q->_first_selected = Timestamp::now();
     }
     bool current_path_valid = _link_table->valid_route(q->_p);
     int current_path_metric = _link_table->get_route_metric(q->_p);
     
-    struct timeval expire;
-    struct timeval now;
-    click_gettimeofday(&now);
-    
-    struct timeval max_switch;
-    max_switch.tv_sec = _time_before_switch_sec;
-    max_switch.tv_usec = 0;
-    timeradd(&q->_last_switch, &max_switch, &expire);
+    Timestamp now = Timestamp::now();
+    Timestamp expire = q->_last_switch + Timestamp(_time_before_switch_sec, 0);
     
     if (!_route_dampening ||
 	!current_path_valid || 
 	current_path_metric > 100 + best_metric ||
-	timercmp(&expire, &now, <)) {
+	expire < now) {
       if (q->_p != best) {
-	click_gettimeofday(&q->_first_selected);
+	q->_first_selected = now;
       }
       q->_p = best;
-      click_gettimeofday(&q->_last_switch);
+      q->_last_switch = now;
     }
     p_in = _sr_forwarder->encap(p_in, q->_p, 0);
     if (p_in) {
@@ -210,11 +202,8 @@
   }
   
   if (do_query) {
-    struct timeval n;
-    click_gettimeofday(&n);
-    struct timeval expire;
-    timeradd(&q->_last_query, &_query_wait, &expire);
-    if (timercmp(&expire, &n, <)) {
+    Timestamp expire = q->_last_query + _query_wait;
+    if (expire < Timestamp::now()) {
       send_query(dst);
     }
   }
@@ -234,8 +223,7 @@
 	return String(td->_debug) + "\n";
     case H_QUERIES: {
         StringAccum sa;
-	struct timeval now;
-	click_gettimeofday(&now);
+	Timestamp now = Timestamp::now();
 	for (SRQuerier::DstTable::const_iterator iter = td->_queries.begin(); iter; iter++) {
 	  SRQuerier::DstInfo dst = iter.value();
 	  sa << dst._ip;
Index: elements/wifi/sr/srquerier.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/srquerier.hh,v
retrieving revision 1.5
diff -u -u -w -r1.5 srquerier.hh
--- elements/wifi/sr/srquerier.hh	30 Dec 2004 16:49:09 -0000	1.5
+++ elements/wifi/sr/srquerier.hh	30 Dec 2004 23:50:35 -0000
@@ -52,10 +52,10 @@
     IPAddress _ip;
     int _best_metric;
     int _count;
-    struct timeval _last_query;
+    Timestamp _last_query;
     Path _p;
-    struct timeval _last_switch;    // last time we picked a new best route
-    struct timeval _first_selected; // when _p was first selected as best route
+    Timestamp _last_switch;    // last time we picked a new best route
+    Timestamp _first_selected; // when _p was first selected as best route
     
   };
 
@@ -63,7 +63,7 @@
   typedef HashMap<IPAddress, DstInfo> DstTable;
   DstTable _queries;
 
-  struct timeval _query_wait;
+  Timestamp _query_wait;
 
   u_long _seq;      // Next query sequence number to use.
   IPAddress _ip;    // My IP address.
Index: elements/wifi/sr/srqueryforwarder.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/srqueryforwarder.cc,v
retrieving revision 1.6
diff -u -u -w -r1.6 srqueryforwarder.cc
--- elements/wifi/sr/srqueryforwarder.cc	5 Oct 2004 18:55:33 -0000	1.6
+++ elements/wifi/sr/srqueryforwarder.cc	30 Dec 2004 23:50:35 -0000
@@ -42,12 +42,9 @@
   MaxHops = 30;
 
   // Pick a starting sequence number that we have not used before.
-  struct timeval tv;
-  click_gettimeofday(&tv);
-  _seq = tv.tv_usec;
+  _seq = Timestamp::now().usec();
 
-  _query_wait.tv_sec = 5;
-  _query_wait.tv_usec = 0;
+  _query_wait = Timestamp(5, 0);
 
 
   static unsigned char bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -171,17 +168,14 @@
   si = _seen.size() - 1;
   
   _seen[si]._count++;
-  click_gettimeofday(&_seen[si]._when);
+  _seen[si]._when = Timestamp::now();
 
   
   /* schedule timer */
   int delay_time = random() % 1750 + 1;
   sr_assert(delay_time > 0);
   
-  struct timeval delay;
-  delay.tv_sec = 0;
-  delay.tv_usec = delay_time*1000;
-  timeradd(&_seen[si]._when, &delay, &_seen[si]._to_send);
+  _seen[si]._to_send = _seen[si]._when + Timestamp::make_msec(delay_time);
   _seen[si]._forwarded = false;
   Timer *t = new Timer(static_forward_query_hook, (void *) this);
   t->initialize(this);
@@ -191,10 +185,9 @@
 void
 SRQueryForwarder::forward_query_hook() 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
   for (int x = 0; x < _seen.size(); x++) {
-    if (timercmp(&_seen[x]._to_send, &now, <) && !_seen[x]._forwarded) {
+    if (_seen[x]._to_send < now && !_seen[x]._forwarded) {
       forward_query(&_seen[x]);
     }
   }
@@ -206,10 +199,8 @@
   s->_forwarded = true;
   _link_table->dijkstra(false);
   if (0) {
-    struct timeval now;
-    click_gettimeofday(&now);
     StringAccum sa;
-    sa << now - s->_when;
+    sa << (Timestamp::now() - s->_when);
     click_chatter("%{element} :: %s :: waited %s\n",
 		  this,
 		  __func__,
Index: elements/wifi/sr/srqueryforwarder.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/srqueryforwarder.hh,v
retrieving revision 1.4
diff -u -u -w -r1.4 srqueryforwarder.hh
--- elements/wifi/sr/srqueryforwarder.hh	3 Dec 2004 21:17:04 -0000	1.4
+++ elements/wifi/sr/srqueryforwarder.hh	30 Dec 2004 23:50:35 -0000
@@ -62,8 +62,8 @@
     u_long _seq;
 
     int _count;
-    struct timeval _when; /* when we saw the first query */
-    struct timeval _to_send;
+    Timestamp _when; /* when we saw the first query */
+    Timestamp _to_send;
     bool _forwarded;
 
 
@@ -84,7 +84,7 @@
 
   int MaxSeen;   // Max size of table of already-seen queries.
   int MaxHops;   // Max hop count for queries.
-  struct timeval _query_wait;
+  Timestamp _query_wait;
   u_long _seq;      // Next query sequence number to use.
   IPAddress _ip;    // My IP address.
   EtherAddress _en; // My ethernet address.
Index: elements/wifi/sr/tokenqueue.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/tokenqueue.cc,v
retrieving revision 1.3
diff -u -u -w -r1.3 tokenqueue.cc
--- elements/wifi/sr/tokenqueue.cc	27 Sep 2004 22:02:34 -0000	1.3
+++ elements/wifi/sr/tokenqueue.cc	30 Dec 2004 23:50:35 -0000
@@ -42,8 +42,7 @@
     set_ninputs(3);
     set_noutputs(2);
     MOD_INC_USE_COUNT;
-    _catchup_timeout.tv_sec = 2;
-    _catchup_timeout.tv_usec = 0;
+    _catchup_timeout = Timestamp(2, 0);
     _tokens = 0;
     _retransmits = 0;
     _normal = 0;
@@ -106,17 +105,11 @@
   if (_sr_forwarder->cast("SRForwarder") == 0) 
     return errh->error("SR element is not a SRForwarder");
 
-  unsigned int active_duration_ms = 15 * 1000;
-  timerclear(&_active_duration);
   /* convehop path_duration from ms to a struct timeval */
-  _active_duration.tv_sec = active_duration_ms/1000;
-  _active_duration.tv_usec = (active_duration_ms % 1000) * 1000;
+  _active_duration = Timestamp::make_msec(15 * 1000);
 
-  unsigned int clear_duration_ms = 30 * 1000;
-  timerclear(&_clear_duration);
   /* convehop path_duration from ms to a struct timeval */
-  _clear_duration.tv_sec = clear_duration_ms/1000;
-  _clear_duration.tv_usec = (clear_duration_ms % 1000) * 1000;
+  _clear_duration = Timestamp::make_msec(30 * 1000);
   
   _timer.initialize(this);
   _timer.schedule_now();
@@ -125,15 +118,11 @@
 void
 TokenQueue::run_timer() 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
   Vector<Path> to_clear;
   Vector<Path> not_active;
 
   for (PathIter iter = _paths.begin(); iter; iter++) {
       const PathInfo &nfo = iter.value();
-      struct timeval expire;
-      timeradd(&nfo._last_real, &_active_duration, &expire);
       if (nfo._active && nfo.active_timedout()) {
 	  not_active.push_back(nfo._p);
       }
@@ -143,15 +132,13 @@
       PathInfo *nfo = _paths.findp(not_active[x]);
       nfo->_active = false;
       if (_debug) {
-	  struct timeval now;
-	  click_gettimeofday(&now);
 	  StringAccum sa;
-	  sa << id() << " " << now;
+	  sa << id() << " " << Timestamp::now();
 	  sa << " mark_inactive " << path_to_string(nfo->_p);
 	  click_chatter("%s", sa.take_string().cc());
       }
   }
-  _timer.schedule_after_ms(_active_duration.tv_sec/2);
+  _timer.schedule_after_ms(_active_duration.sec()/2);
 }
 TokenQueue::PathInfo *
 TokenQueue::find_path_info(Path p)
@@ -227,11 +214,10 @@
     bool follow_up = false;
     Path p = Path();
     PathInfo *nfo = NULL;
-    struct timeval now;
+    Timestamp now = Timestamp::now();
     if (!_normal && !_tokens && !_retransmits) {
 	goto done;
     }
-    click_gettimeofday(&now);
     packet = yank1(yank_filter(this, Path()));
     if (packet) {
 	p_in = packet->uniqueify();
@@ -457,21 +443,16 @@
     }
     if (!nfo) {
 	if (_debug) {
-	    struct timeval now;
-	    click_gettimeofday(&now);
 	    StringAccum sa;
-	    sa << id() << " " << now;
+	    sa << id() << " " << Timestamp::now();
 	    sa << " create:  new_path " << path_to_string(p);
 	    click_chatter("%s", sa.take_string().cc());
 	}
 	_paths.insert(p, PathInfo(p, this));
 	nfo = _paths.findp(p);
 
-	click_gettimeofday(&nfo->_last_tx);
-	click_gettimeofday(&nfo->_last_rx);
-	click_gettimeofday(&nfo->_first_tx);
-	click_gettimeofday(&nfo->_first_rx);
-	click_gettimeofday(&nfo->_last_real);
+	nfo->_last_tx = nfo->_last_rx = nfo->_first_tx = nfo->_first_rx
+	    = nfo->_last_real = Timestamp::now();
 	nfo->_active = false;
     }
 
@@ -479,7 +460,7 @@
      * or if we're new *
      */
     if (!nfo->_active) {
-	click_gettimeofday(&nfo->_last_real);
+	nfo->_last_real = Timestamp::now();
 	nfo->_active = true;
 	nfo->_token = true;
 	_tokens++;
@@ -491,8 +472,7 @@
 {
     Path p = pk->get_path();
     PathInfo *nfo = find_path_info(p);
-    struct timeval now;
-    click_gettimeofday(&now);
+    Timestamp now = Timestamp::now();
 
     IPAddress towards = p[p.size()-1];
 
@@ -665,8 +645,7 @@
 {
   StringAccum sa;
 
-  struct timeval now;
-  click_gettimeofday(&now);
+  Timestamp now = Timestamp::now();
 
   sa << " tokens " << _tokens;
   sa << " retransmits " << _retransmits;
@@ -682,7 +661,7 @@
       sa << " last_rx " << now - nfo._last_rx;
       sa << " packets_rx " << nfo._packets_rx;
       sa << " expected_rx " << nfo._expected_rx;
-      sa << " last_tx " << now - nfo._last_tx;
+      sa << " last_tx " << (now - nfo._last_tx);
       sa << " packets_tx " << nfo._packets_tx;
       sa << "\n";
   }
Index: elements/wifi/sr/tokenqueue.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/sr/tokenqueue.hh,v
retrieving revision 1.1
diff -u -u -w -r1.1 tokenqueue.hh
--- elements/wifi/sr/tokenqueue.hh	27 May 2004 16:13:43 -0000	1.1
+++ elements/wifi/sr/tokenqueue.hh	30 Dec 2004 23:50:35 -0000
@@ -41,18 +41,18 @@
     void run_timer();
 private:
     int _drops;
-    struct timeval _catchup_timeout;
+    Timestamp _catchup_timeout;
 
     class PathInfo {
     public:
 	TokenQueue *_q;
 	Path _p;
 	unsigned int _seq;
-	struct timeval _last_tx;
-	struct timeval _first_tx;
-	struct timeval _first_rx;
-	struct timeval _last_rx;
-	struct timeval _last_real;
+	Timestamp _last_tx;
+	Timestamp _first_tx;
+	Timestamp _first_rx;
+	Timestamp _last_rx;
+	Timestamp _last_real;
 	int _packets_tx;
 	int _packets_rx;
 	int _expected_rx;
@@ -93,9 +93,6 @@
 	}
 
 	bool rt_timedout() const {
-	    struct timeval expire;
-	    struct timeval now;
-	    click_gettimeofday(&now);
 	    if (!_q) {
 		return false;
 	    }
@@ -105,35 +102,24 @@
 	    unsigned int rt_duration_ms = 
 		(_q->_threshold * _q->_max_tx_packet_ms * (_p.size()+1));
 	    
-	    struct timeval rt_duration;
-	    timerclear(&rt_duration);
-	    rt_duration.tv_sec = rt_duration_ms/1000;
-	    rt_duration.tv_usec = (rt_duration_ms % 1000) * 1000;
-	    
-	    timeradd(&_last_tx, &rt_duration, &expire);
-	    return timercmp(&expire, &now, <);
+	    Timestamp expire = _last_tx + Timestamp::make_msec(rt_duration_ms);
+	    return expire < Timestamp::now();
 	}
 
 	bool active_timedout() const {
-	    struct timeval expire;
-	    struct timeval now;
-	    click_gettimeofday(&now);
 	    if (!_q) {
 		return false;
 	    }
-	    timeradd(&_last_real, &_q->_active_duration, &expire);
-	    return timercmp(&expire, &now, <);
+	    Timestamp expire = _last_real + _q->_active_duration;
+	    return expire < Timestamp::now();
 	}
 
 	bool clear_timedout() const {
-	    struct timeval expire;
-	    struct timeval now;
-	    click_gettimeofday(&now);
 	    if (!_q || _active) {
 		return false;
 	    }
-	    timeradd(&_last_real, &_q->_clear_duration, &expire);
-	    return timercmp(&expire, &now, <);
+	    Timestamp expire = _last_real + _q->_clear_duration;
+	    return expire < Timestamp::now();
 	}
 
     };
@@ -185,8 +171,8 @@
     bool _debug;
     int _threshold;
     unsigned int _max_tx_packet_ms;
-    struct timeval _active_duration;
-    struct timeval _clear_duration;
+    Timestamp _active_duration;
+    Timestamp _clear_duration;
     Timer _timer;
     int _tokens;
     int _retransmits;
Index: elements/wifi/station/beacontracker.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/station/beacontracker.cc,v
retrieving revision 1.1
diff -u -u -w -r1.1 beacontracker.cc
--- elements/wifi/station/beacontracker.cc	23 Dec 2004 05:01:16 -0000	1.1
+++ elements/wifi/station/beacontracker.cc	30 Dec 2004 23:50:35 -0000
@@ -145,16 +145,8 @@
 void
 BeaconTracker::trim() 
 {
-  struct timeval now;
-  click_gettimeofday(&now);
-  
-  int f = _track * _beacon_int;
-  struct timeval earliest;
-  struct timeval diff = {f / 1000, f % 1000};
-
-  timersub(&now, &diff, &earliest);
-
-  while (_beacons.size() && timercmp(&_beacons[0].rx, &earliest, <)) {
+  Timestamp earliest = Timestamp::now() - Timestamp::make_msec(_track * _beacon_int);
+  while (_beacons.size() && _beacons[0].rx < earliest) {
     _beacons.pop_front();
   }  
 
Index: elements/wifi/station/beacontracker.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/elements/wifi/station/beacontracker.hh,v
retrieving revision 1.1
diff -u -u -w -r1.1 beacontracker.hh
--- elements/wifi/station/beacontracker.hh	23 Dec 2004 05:01:16 -0000	1.1
+++ elements/wifi/station/beacontracker.hh	30 Dec 2004 23:50:35 -0000
@@ -40,7 +40,7 @@
   Packet *simple_action(Packet *);
 
   struct beacon_t {
-    struct timeval rx;
+    Timestamp rx;
     uint16_t seq;
   };
   DEQueue<beacon_t> _beacons;
Index: include/click/confparse.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/confparse.hh,v
retrieving revision 1.52
diff -u -u -w -r1.52 confparse.hh
--- include/click/confparse.hh	17 Jul 2004 21:44:43 -0000	1.52
+++ include/click/confparse.hh	30 Dec 2004 23:50:36 -0000
@@ -6,6 +6,7 @@
 CLICK_DECLS
 class ErrorHandler;
 class StringAccum;
+class Timestamp;
 #ifndef CLICK_TOOL
 class Element;
 class Router;
@@ -105,7 +106,8 @@
 bool cp_seconds_as(int want_power, const String&, uint32_t*);
 bool cp_seconds_as_milli(const String&, uint32_t*);
 bool cp_seconds_as_micro(const String&, uint32_t*);
-bool cp_timeval(const String&, struct timeval*);
+bool cp_time(const String&, timeval*);
+bool cp_time(const String&, Timestamp*);
 
 bool cp_bandwidth(const String&, uint32_t*);
 
@@ -124,7 +126,8 @@
 String cp_unparse_real10(uint32_t, int frac_digits);
 String cp_unparse_milliseconds(uint32_t);
 String cp_unparse_microseconds(uint32_t);
-String cp_unparse_interval(const struct timeval&);
+String cp_unparse_interval(const timeval&);
+String cp_unparse_interval(const Timestamp&);
 String cp_unparse_bandwidth(uint32_t);
 
 // network addresses
@@ -206,8 +209,9 @@
     cpSeconds,		//			uint32_t*
     cpSecondsAsMilli,	//			uint32_t* milliseconds
     cpSecondsAsMicro,	//			uint32_t* microseconds
-    cpTimeval,		//			struct timeval*
-    cpInterval,		//			struct timeval*
+    cpTimeval,		//			timeval*
+    cpTimestamp,	//			Timestamp*
+    cpInterval,		//			timeval*
     cpBandwidth,	//			uint32_t* bandwidth (in B/s)
     cpIPAddress,	//			IPAddress*
     cpIPPrefix,		//			IPAddress* a, IPAddress* mask
Index: include/click/gaprate.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/gaprate.hh,v
retrieving revision 1.6
diff -u -u -w -r1.6 gaprate.hh
--- include/click/gaprate.hh	4 May 2004 17:28:30 -0000	1.6
+++ include/click/gaprate.hh	30 Dec 2004 23:50:36 -0000
@@ -1,7 +1,7 @@
 // -*- c-basic-offset: 4; related-file-name: "../../lib/gaprate.cc" -*-
 #ifndef CLICK_GAPRATE_HH
 #define CLICK_GAPRATE_HH
-#include <click/glue.hh>
+#include <click/timestamp.hh>
 CLICK_DECLS
 class ErrorHandler;
 
@@ -16,7 +16,7 @@
     void set_rate(unsigned, ErrorHandler *);
     inline void reset();
 
-    inline bool need_update(const struct timeval &);
+    inline bool need_update(const Timestamp &);
     void update()				{ _sec_count++; }
     void update_with(int incr)			{ _sec_count += incr; }
 
@@ -30,7 +30,7 @@
     int _tv_sec;
     unsigned _rate;
 #if DEBUG_GAPRATE
-    struct timeval _last;
+    Timestamp _last;
 #endif
 
 };
@@ -40,7 +40,7 @@
 {
     _tv_sec = -1;
 #if DEBUG_GAPRATE
-    _last.tv_sec = 0;
+    _last._sec = 0;
 #endif
 }
 
@@ -70,20 +70,20 @@
 }
 
 inline bool
-GapRate::need_update(const struct timeval &now)
+GapRate::need_update(const Timestamp &now)
 {
     if (_tv_sec < 0) {
-	_tv_sec = now.tv_sec;
-	_sec_count = ((now.tv_usec << UGAP_SHIFT) / _ugap) + 1;
-    } else if (now.tv_sec > _tv_sec) {
-	_tv_sec = now.tv_sec;
+	_tv_sec = now.sec();
+	_sec_count = ((now.usec() << UGAP_SHIFT) / _ugap) + 1;
+    } else if (now.sec() > _tv_sec) {
+	_tv_sec = now.sec();
 	if (_sec_count > 0)
 	    _sec_count -= _rate;
     }
 
-    unsigned need = (now.tv_usec << UGAP_SHIFT) / _ugap;
+    unsigned need = (now.usec() << UGAP_SHIFT) / _ugap;
 #if DEBUG_GAPRATE
-    click_chatter("%lu.%06lu -> %u @ %u [%d]", now.tv_sec, now.tv_usec, need, _sec_count, (int)need >= _sec_count);
+    click_chatter("%{timestamp} -> %u @ %u [%d]", &now, need, _sec_count, (int)need >= _sec_count);
 #endif
     return ((int)need >= _sec_count);
 }
Index: include/click/glue.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/glue.hh,v
retrieving revision 1.42
diff -u -u -w -r1.42 glue.hh
--- include/click/glue.hh	1 Aug 2004 02:31:17 -0000	1.42
+++ include/click/glue.hh	30 Dec 2004 23:50:36 -0000
@@ -224,8 +224,8 @@
 // TIMEVAL OPERATIONS
 
 #ifndef timercmp
-/* Convenience macros for operations on timevals.
-   NOTE: `timercmp' does not work for >= or <=.  */
+// Convenience macros for operations on timevals.
+// NOTE: 'timercmp' does not work for >= or <=.
 # define timerisset(tvp)	((tvp)->tv_sec || (tvp)->tv_usec)
 # define timerclear(tvp)	((tvp)->tv_sec = (tvp)->tv_usec = 0)
 # define timercmp(a, b, CMP)			\
@@ -342,65 +342,28 @@
     return a;
 }
 
-# if !CLICK_LINUXMODULE && !CLICK_BSDMODULE
-inline double
-timeval2double(const struct timeval &a)
-{
-    return a.tv_sec + (a.tv_usec / 1000000.);
-}
-
-inline struct timeval
-double2timeval(double d)
-{
-    uint32_t sec = (uint32_t)d;
-    uint32_t usec = (uint32_t)((d - sec)*1000000 + 0.5);
-    return make_timeval(sec, usec);
-}
-
-inline struct timeval
-operator*(const struct timeval &a, double b)
-{
-    return double2timeval(timeval2double(a) * b);
-}
-
-inline struct timeval
-operator*(double a, const struct timeval &b)
-{
-    return double2timeval(timeval2double(b) * a);
-}
+#endif
 
-inline struct timeval
-operator/(const struct timeval &a, double b)
-{
-    return double2timeval(timeval2double(a) / b);
-}
+CLICK_DECLS
+class StringAccum;
+StringAccum &operator<<(StringAccum &, const struct timeval &);
+CLICK_ENDDECLS
 
-inline double
-operator/(const struct timeval &a, const struct timeval &b)
-{
-    return timeval2double(a) / timeval2double(b);
-}
-# endif /* !CLICK_LINUXMODULE && !CLICK_BSDMODULE */
 
-#endif
-
-// byte order
+// BYTE ORDER
 
 #if CLICK_BYTE_ORDER == CLICK_BIG_ENDIAN
-
 #define le16_to_cpu(x) bswap_16((x))
 #define cpu_to_le16(x) bswap_16((x))
 #define le32_to_cpu(x) bswap_32((x))
 #define cpu_to_le32(x) bswap_32((x))
-
 #else
-
 #define le16_to_cpu(x) (x)
 #define cpu_to_le16(x) (x)
 #define le32_to_cpu(x) (x)
 #define cpu_to_le32(x) (x)
-
 #endif
+
 
 // CYCLE COUNTS
 
Index: include/click/master.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/master.hh,v
retrieving revision 1.8
diff -u -u -w -r1.8 master.hh
--- include/click/master.hh	9 Nov 2004 19:22:48 -0000	1.8
+++ include/click/master.hh	30 Dec 2004 23:50:36 -0000
@@ -33,7 +33,7 @@
 
     const volatile int* runcount_ptr() const	{ return &_runcount; }
     
-    int timer_delay(struct timeval*);
+    int timer_delay(Timestamp*);
     void run_timers();
     
 #if CLICK_USERLEVEL
Index: include/click/packet.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/packet.hh,v
retrieving revision 1.49
diff -u -u -w -r1.49 packet.hh
--- include/click/packet.hh	2 Dec 2004 20:03:13 -0000	1.49
+++ include/click/packet.hh	30 Dec 2004 23:50:36 -0000
@@ -3,6 +3,7 @@
 #define CLICK_PACKET_HH
 #include <click/ipaddress.hh>
 #include <click/glue.hh>
+#include <click/timestamp.hh>
 #ifdef CLICK_LINUXMODULE
 # include <click/skbmgr.hh>
 #endif
@@ -186,10 +187,9 @@
   void set_dst_ip6_anno(const IP6Address &);
 
 #ifdef CLICK_LINUXMODULE
-  const struct timeval &timestamp_anno() const { return skb()->stamp; }
-  struct timeval &timestamp_anno()	{ return skb()->stamp; }
-  void set_timestamp_anno(const struct timeval &tv) { skb()->stamp = tv; }
-  void set_timestamp_anno(int s, int us) { skb()->stamp.tv_sec = s; skb()->stamp.tv_usec = us; }
+  const Timestamp &timestamp_anno() const { return *(const Timestamp*) &skb()->stamp; }
+  Timestamp &timestamp_anno()		{ return *(Timestamp*) &skb()->stamp; }
+  void set_timestamp_anno(const Timestamp &tv) { memcpy(&skb()->stamp, &tv, 8); }
   net_device *device_anno() const	{ return skb()->dev; }
   void set_device_anno(net_device *dev)	{ skb()->dev = dev; }
   PacketType packet_type_anno() const	{ return (PacketType)(skb()->pkt_type & PACKET_TYPE_MASK); }
@@ -201,10 +201,9 @@
 
 #else			/* User-space and BSD kernel module */
 
-  const struct timeval &timestamp_anno() const { return _timestamp; }
-  struct timeval &timestamp_anno()	{ return _timestamp; }
-  void set_timestamp_anno(const struct timeval &tv) { _timestamp = tv; }
-  void set_timestamp_anno(int s, int us) { _timestamp.tv_sec = s; _timestamp.tv_usec = us; }
+  const Timestamp &timestamp_anno() const { return _timestamp; }
+  Timestamp &timestamp_anno()		{ return _timestamp; }
+  void set_timestamp_anno(const Timestamp &tv) { _timestamp = tv; }
 #ifdef CLICK_NS
   class SimPacketinfoWrapper {
   public:
@@ -317,7 +316,7 @@
     click_icmp *icmph;
   } _h;
   PacketType _pkt_type;
-  struct timeval _timestamp;
+  Timestamp _timestamp;
 #ifdef CLICK_BSDMODULE
   struct mbuf *_m;
 #endif
@@ -814,7 +813,7 @@
   memset(anno(), '\0', sizeof(Anno));
   set_packet_type_anno(HOST);
   set_device_anno(0);
-  set_timestamp_anno(0, 0);
+  set_timestamp_anno(Timestamp());
   set_mac_header(0);
   set_network_header(0, 0);
   set_next(0);
Index: include/click/packet_anno.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/packet_anno.hh,v
retrieving revision 1.25
diff -u -u -w -r1.25 packet_anno.hh
--- include/click/packet_anno.hh	20 Oct 2004 02:35:53 -0000	1.25
+++ include/click/packet_anno.hh	30 Dec 2004 23:50:36 -0000
@@ -49,7 +49,7 @@
 #define SET_PACKET_NUMBER_ANNO(p, n, v)	((p)->set_user_anno_u(4 + (n), (v)))
 
 // bytes 16-23
-#define FIRST_TIMESTAMP_ANNO(p)		(*((const struct timeval *)((p)->all_user_anno_u() + 4)))
-#define SET_FIRST_TIMESTAMP_ANNO(p, v)	(*((struct timeval *)((p)->all_user_anno_u() + 4)) = (v))
+#define FIRST_TIMESTAMP_ANNO(p)		(*((const Timestamp*) ((p)->all_user_anno_u() + 4)))
+#define SET_FIRST_TIMESTAMP_ANNO(p, v)	(*((Timestamp*) ((p)->all_user_anno_u() + 4)) = (v))
 
 #endif
Index: include/click/straccum.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/straccum.hh,v
retrieving revision 1.30
diff -u -u -w -r1.30 straccum.hh
--- include/click/straccum.hh	16 May 2004 20:37:52 -0000	1.30
+++ include/click/straccum.hh	30 Dec 2004 23:50:36 -0000
@@ -99,7 +99,6 @@
 #if defined(CLICK_USERLEVEL) || defined(CLICK_TOOL)
 StringAccum &operator<<(StringAccum &, double);
 #endif
-StringAccum &operator<<(StringAccum &, const struct timeval &);
 
 StringAccum &operator<<(StringAccum &, void *);
 
Index: include/click/timer.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/timer.hh,v
retrieving revision 1.24
diff -u -u -w -r1.24 timer.hh
--- include/click/timer.hh	9 Nov 2004 19:22:48 -0000	1.24
+++ include/click/timer.hh	30 Dec 2004 23:50:36 -0000
@@ -4,6 +4,7 @@
 #include <click/sync.hh>
 #include <click/glue.hh>
 #include <click/element.hh>
+#include <click/timestamp.hh>
 CLICK_DECLS
 class Element;
 class Router;
@@ -21,21 +22,21 @@
 
     bool initialized() const		{ return _router != 0; }
     bool scheduled() const		{ return _schedpos >= 0; }
-    const timeval &expiry() const	{ return _expiry; }
+    const Timestamp &expiry() const	{ return _expiry; }
   
     inline void initialize(Router *);
     inline void initialize(Element *);
     void cleanup()			{ unschedule(); }
     void uninitialize()			{ cleanup(); }	// deprecated
 
-    void schedule_at(const timeval &);
-    inline void reschedule_at(const timeval &); // synonym
+    void schedule_at(const Timestamp&);
+    inline void reschedule_at(const Timestamp&); // synonym
 
     inline void schedule_now();
-    void schedule_after(const timeval &);
+    void schedule_after(const Timestamp&);
     inline void schedule_after_s(uint32_t);
     inline void schedule_after_ms(uint32_t);
-    inline void reschedule_after(const timeval &);
+    inline void reschedule_after(const Timestamp&);
     inline void reschedule_after_s(uint32_t);
     inline void reschedule_after_ms(uint32_t);
 
@@ -44,7 +45,7 @@
   private:
   
     int _schedpos;
-    timeval _expiry;
+    Timestamp _expiry;
     TimerHook _hook;
     void *_thunk;
     Router *_router;
@@ -70,9 +71,9 @@
 }
 
 inline void
-Timer::reschedule_at(const timeval &tv)
+Timer::reschedule_at(const Timestamp &ts)
 {
-    schedule_at(tv);
+    schedule_at(ts);
 }
 
 inline void
@@ -84,17 +85,17 @@
 inline void
 Timer::schedule_after_s(uint32_t s)
 {
-    schedule_after(make_timeval(s, 0));
+    schedule_after(Timestamp(s, 0));
 }
 
 inline void
 Timer::schedule_after_ms(uint32_t ms)
 {
-    schedule_after(make_timeval(ms / 1000, (ms % 1000) * 1000));
+    schedule_after(Timestamp::make_msec(ms));
 }
 
 inline void
-Timer::reschedule_after(const timeval &delta)
+Timer::reschedule_after(const Timestamp &delta)
 {
     schedule_at(_expiry + delta);
 }
@@ -102,13 +103,13 @@
 inline void
 Timer::reschedule_after_s(uint32_t s)
 {
-    schedule_at(make_timeval(s + _expiry.tv_sec, _expiry.tv_usec));
+    schedule_at(Timestamp(_expiry.sec() + s, _expiry.subsec()));
 }
 
 inline void
 Timer::reschedule_after_ms(uint32_t ms)
 {
-    schedule_at(_expiry + make_timeval(ms / 1000, (ms % 1000) * 1000));
+    schedule_at(_expiry + Timestamp::make_msec(ms));
 }
 
 CLICK_ENDDECLS
Index: include/click/timestamp.hh
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/include/click/timestamp.hh,v
retrieving revision 1.1
diff -u -u -w -r1.1 timestamp.hh
--- include/click/timestamp.hh	30 Dec 2004 23:28:26 -0000	1.1
+++ include/click/timestamp.hh	30 Dec 2004 23:50:36 -0000
@@ -28,7 +28,7 @@
     enum { SUBSEC_PER_SEC = 1000000 };
     inline static int32_t msec_to_subsec(int32_t m)	{ return m * 1000; }
     inline static int32_t usec_to_subsec(int32_t u)	{ return u; }
-    inline static int32_t nsec_to_subsec(int32_t n)	{ return n / 1000; }
+    inline static int32_t nsec_to_subsec(int32_t n)	{ return (n + 500) / 1000; }
     inline static int32_t subsec_to_msec(int32_t ss)	{ return ss / 1000; }
     inline static int32_t subsec_to_usec(int32_t ss)	{ return ss; }
     inline static int32_t subsec_to_nsec(int32_t ss)	{ return ss * 1000; }
Index: lib/confparse.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/lib/confparse.cc,v
retrieving revision 1.136
diff -u -u -w -r1.136 confparse.cc
--- lib/confparse.cc	18 Dec 2004 02:30:24 -0000	1.136
+++ lib/confparse.cc	30 Dec 2004 23:50:36 -0000
@@ -41,6 +41,7 @@
 # define CP_PASS_CONTEXT , context
 #else
 # include <click/hashmap.hh>
+# include <click/timestamp.hh>
 # define CP_CONTEXT_ARG
 # define CP_PASS_CONTEXT
 #endif
@@ -1292,24 +1293,28 @@
   return cp_seconds_as(6, str_in, return_value);
 }
 
-bool cp_timeval(const String &str, struct timeval *return_value)
+bool cp_time(const String &str, Timestamp* return_value)
 {
   int power = 0, factor = 1;
   const char *after_unit = read_unit(str.begin(), str.end(), seconds_units, sizeof(seconds_units), seconds_prefixes, &power, &factor);
-  uint32_t tv_sec, tv_usec;
-  if (!cp_unsigned_real10(str.substring(str.begin(), after_unit), 6, power, &tv_sec, &tv_usec))
+    uint32_t sec, nsec;
+    if (!cp_unsigned_real10(str.substring(str.begin(), after_unit), 9, power, &sec, &nsec))
     return false;
   if (factor != 1) {
-    tv_usec *= factor;
-    int delta = tv_usec / 1000000;
-    tv_usec -= delta * 1000000;
-    tv_sec = (tv_sec * factor) + delta;
+	nsec *= factor;
+	int delta = nsec / 1000000000;
+	nsec -= delta * 1000000000;
+	sec = (sec * factor) + delta;
   }
-  return_value->tv_sec = tv_sec;
-  return_value->tv_usec = tv_usec;
+    *return_value = Timestamp::make_nsec(sec, nsec);
   return true;
 }
 
+bool cp_time(const String &str, timeval *return_value)
+{
+    return cp_time(str, (Timestamp*) return_value);
+}
+
 
 static const char byte_bandwidth_units[] = "\
 \3\175\1baud\
@@ -1959,6 +1964,7 @@
   cpSecondsAsMilli	= "msec",
   cpSecondsAsMicro	= "usec",
   cpTimeval		= "timeval",
+  cpTimestamp		= "timestamp",
   cpInterval		= "interval",
   cpBandwidth		= "bandwidth_Bps",
   cpIPAddress		= "ip_addr",
@@ -2250,7 +2256,7 @@
    case cpiTimeval:
    case cpiInterval: {
      struct timeval tv;
-     if (!cp_timeval(arg, &tv)) {
+     if (!cp_time(arg, &tv)) {
        if (cp_errno == CPE_NEGATIVE)
 	 errh->error("%s (%s) must be >= 0", argname, desc);
        else
@@ -3456,18 +3462,24 @@
 }
 
 String
-cp_unparse_interval(const struct timeval &tv)
+cp_unparse_interval(const Timestamp& ts)
 {
-  if (!tv.tv_sec)
-    return cp_unparse_microseconds(tv.tv_usec);
+    if (ts.sec() == 0)
+	return cp_unparse_microseconds(ts.usec());
   else {
     StringAccum sa;
-    sa << tv << 's';
+	sa << ts << 's';
     return sa.take_string();
   }
 }
 
 String
+cp_unparse_interval(const timeval& tv)
+{
+    return cp_unparse_interval(*(const Timestamp*) &tv);
+}
+
+String
 cp_unparse_bandwidth(uint32_t bw)
 {
   if (bw >= 0x20000000U)
@@ -3524,6 +3536,7 @@
     cp_register_argtype(cpSecondsAsMilli, "time in sec (msec precision)", 0, default_parsefunc, default_storefunc, cpiSecondsAsMilli);
     cp_register_argtype(cpSecondsAsMicro, "time in sec (usec precision)", 0, default_parsefunc, default_storefunc, cpiSecondsAsMicro);
     cp_register_argtype(cpTimeval, "seconds since the epoch", 0, default_parsefunc, default_storefunc, cpiTimeval);
+    cp_register_argtype(cpTimestamp, "seconds since the epoch", 0, default_parsefunc, default_storefunc, cpiTimeval);
     cp_register_argtype(cpInterval, "time in sec (usec precision)", 0, default_parsefunc, default_storefunc, cpiInterval);
     cp_register_argtype(cpBandwidth, "bandwidth", 0, default_parsefunc, default_storefunc, cpiBandwidth);
     cp_register_argtype(cpIPAddress, "IP address", 0, default_parsefunc, default_storefunc, cpiIPAddress);
Index: lib/error.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/lib/error.cc,v
retrieving revision 1.52
diff -u -u -w -r1.52 error.cc
--- lib/error.cc	16 Sep 2004 07:10:38 -0000	1.52
+++ lib/error.cc	30 Dec 2004 23:50:36 -0000
@@ -22,6 +22,7 @@
 #ifndef CLICK_TOOL
 # include <click/element.hh>
 #endif
+#include <click/timestamp.hh>
 #include <click/hashmap.hh>
 #include <click/confparse.hh>
 CLICK_DECLS
@@ -645,6 +646,18 @@
     return "(null)";
 }
 
+static String
+timestamp_error_hook(int, VA_LIST_REF_T val)
+{
+  const Timestamp *tsp = va_arg(VA_LIST_DEREF(val), const Timestamp *);
+  if (tsp) {
+    StringAccum sa;
+    sa << *tsp;
+    return sa.take_string();
+  } else
+    return "(null)";
+}
+
 #ifndef CLICK_TOOL
 static String
 element_error_hook(int, VA_LIST_REF_T val)
@@ -663,6 +676,7 @@
   the_default_handler = default_handler;
   the_silent_handler = new SilentErrorHandler;
   add_conversion("timeval", timeval_error_hook);
+  add_conversion("timestamp", timestamp_error_hook);
 #ifndef CLICK_TOOL
   add_conversion("element", element_error_hook);
 #endif
Index: lib/master.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/lib/master.cc,v
retrieving revision 1.17
diff -u -u -w -r1.17 master.cc
--- lib/master.cc	7 Dec 2004 20:24:32 -0000	1.17
+++ lib/master.cc	30 Dec 2004 23:50:39 -0000
@@ -357,23 +357,19 @@
 // How long until next timer expires.
 
 int
-Master::timer_delay(struct timeval* tv)
+Master::timer_delay(Timestamp* tv)
 {
     int retval;
     _timer_lock.acquire();
     if (_timer_heap.size() == 0) {
-	tv->tv_sec = 1000;
-	tv->tv_usec = 0;
+	*tv = Timestamp(1000, 0);
 	retval = 0;
     } else {
-	struct timeval now;
-	click_gettimeofday(&now);
-	if (timercmp(&_timer_heap.at_u(0)->_expiry, &now, >)) {
-	    timersub(&_timer_heap.at_u(0)->_expiry, &now, tv);
-	} else {
-	    tv->tv_sec = 0;
-	    tv->tv_usec = 0;
-	}
+	Timestamp now = Timestamp::now();
+	if (_timer_heap.at_u(0)->_expiry > now)
+	    *tv = _timer_heap.at_u(0)->_expiry - now;
+	else
+	    *tv = Timestamp();
 	retval = 1;
     }
     _timer_lock.release();
@@ -385,8 +381,7 @@
 {
     if (_master_lock.attempt()) {
 	if (_master_paused == 0 && _timer_lock.attempt()) {
-	    struct timeval now;
-	    click_gettimeofday(&now);
+	    Timestamp now = Timestamp::now();
 	    Timer* t;
 	    while (_timer_heap.size() > 0 && _runcount > 0
 		   && (t = _timer_heap.at_u(0), t->_expiry <= now)) {
@@ -562,16 +557,19 @@
     if (more_tasks)
 	timeout = 0;
     else {
-	struct timeval wait;
+	Timestamp wait;
 	bool timers = timer_delay(&wait);
-	timeout = (timers ? wait.tv_sec * 1000 + wait.tv_usec / 1000 : -1);
+	timeout = (timers ? (int) wait.msec1() : -1);
     }
 # else /* !HAVE_POLL_H */
-    struct timeval wait, *wait_ptr = &wait;
+    Timestamp wait;
+    struct timeval *wait_ptr = (struct timeval*) &wait;
     if (more_tasks)
-	timerclear(&wait);
+	/* nada */;
     else if (!timer_delay(&wait))
 	wait_ptr = 0;
+    else
+	wait.convert_to_timeval();
 # endif /* HAVE_POLL_H */
 #endif /* CLICK_NS */
 
Index: lib/straccum.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/lib/straccum.cc,v
retrieving revision 1.35
diff -u -u -w -r1.35 straccum.cc
--- lib/straccum.cc	16 May 2004 20:37:52 -0000	1.35
+++ lib/straccum.cc	30 Dec 2004 23:50:39 -0000
@@ -21,6 +21,7 @@
 #include <click/string.hh>
 #include <click/glue.hh>
 #include <click/confparse.hh>
+#include <click/timestamp.hh>
 #include <stdarg.h>
 CLICK_DECLS
 
@@ -144,20 +145,6 @@
     return sa;
 }
 #endif
-
-StringAccum &
-operator<<(StringAccum &sa, const struct timeval &tv)
-{
-    if (char *x = sa.reserve(30)) {
-	int len;
-	if (tv.tv_sec >= 0)
-	    len = sprintf(x, "%ld.%06ld", (long)tv.tv_sec, (long)tv.tv_usec);
-	else
-	    len = sprintf(x, "-%ld.%06ld", -((long)tv.tv_sec) - 1L, 1000000L - (long)tv.tv_usec);
-	sa.forward(len);
-    }
-    return sa;
-}
 
 StringAccum &
 operator<<(StringAccum &sa, void *v)
Index: lib/timer.cc
===================================================================
RCS file: /home/am0/click/cvsroot/release/one/lib/timer.cc,v
retrieving revision 1.34
diff -u -u -w -r1.34 timer.cc
--- lib/timer.cc	9 Nov 2004 19:22:48 -0000	1.34
+++ lib/timer.cc	30 Dec 2004 23:50:39 -0000
@@ -64,7 +64,7 @@
 }
 
 void
-Timer::schedule_at(const timeval& when)
+Timer::schedule_at(const Timestamp& when)
 {
     // acquire lock, unschedule
     assert(_router && initialized());
@@ -90,11 +90,9 @@
 }
 
 void
-Timer::schedule_after(const timeval &delta)
+Timer::schedule_after(const Timestamp &delta)
 {
-    timeval t;
-    click_gettimeofday(&t);
-    schedule_at(t + delta);
+    schedule_at(Timestamp::now() + delta);
 }
 
 void


More information about the click mailing list