Index: c/src/exec/libnetworking/lib/rtems_bsdnet_ntp.c
===================================================================
--- c/src/exec/libnetworking/lib/rtems_bsdnet_ntp.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
+++ c/src/exec/libnetworking/lib/rtems_bsdnet_ntp.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -0,0 +1,160 @@
+/*
+ * Synchronize with an NTP server
+ *
+ * This program may be distributed and used for any purpose.
+ * I ask only that you:
+ *      1. Leave this author information intact.
+ *      2. Document any changes you make.
+ *
+ * W. Eric Norum
+ * Canadian Light Source
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@cls.usask.ca
+ *
+ *  $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <limits.h>
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/error.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/*
+ * RTEMS base: 1988, January 1
+ *  UNIX base: 1970, January 1
+ *   NTP base: 1900, January 1
+ */
+#define UNIX_BASE_TO_NTP_BASE (((70UL*365UL)+17UL) * (24*60*60))
+
+struct timestamp {
+	rtems_unsigned32	integer;
+	rtems_unsigned32	fraction;
+};
+
+struct ntpPacketSmall {
+	rtems_unsigned8		li_vn_mode;
+	rtems_unsigned8		stratum;
+	rtems_signed8		poll_interval;
+	rtems_signed8		precision;
+	rtems_signed32		root_delay;
+	rtems_signed32		root_dispersion;
+	char			reference_identifier[4];
+	struct timestamp	reference_timestamp;
+	struct timestamp	originate_timestamp;
+	struct timestamp	receive_timestamp;
+	struct timestamp	transmit_timestamp;
+};
+
+struct ntpPacket {
+	struct ntpPacketSmall	ntp;
+	char			authenticator[96];
+};
+
+static int
+processPacket (struct ntpPacketSmall *p)
+{
+	time_t tbuf;
+	struct tm *lt;
+	rtems_time_of_day rt;
+	rtems_interval ticks_per_second;
+
+	if (((p->li_vn_mode & (0x7 << 3)) != (3 << 3))
+	 || ((p->transmit_timestamp.integer == 0) && (p->transmit_timestamp.fraction == 0)))
+		return 0;
+	rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+	tbuf = ntohl (p->transmit_timestamp.integer) - UNIX_BASE_TO_NTP_BASE - rtems_bsdnet_timeoffset;
+	lt = gmtime (&tbuf);
+	rt.year = lt->tm_year + 1900;
+	rt.month = lt->tm_mon + 1;
+	rt.day = lt->tm_mday;
+	rt.hour = lt->tm_hour;
+	rt.minute = lt->tm_min;
+	rt.second = lt->tm_sec;
+	rt.ticks = ntohl (p->transmit_timestamp.fraction) / (ULONG_MAX / ticks_per_second);
+	if (rt.ticks >= ticks_per_second)
+		rt.ticks = ticks_per_second - 1;
+	rtems_clock_set (&rt);
+	return 1;
+}
+
+int
+rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority)
+{
+	int s;
+	int i;
+	static struct sockaddr_in myAddr, farAddr;
+	int fromlen;
+	struct ntpPacketSmall packet;
+	struct timeval tv;
+
+	if (interval != 0) {
+		printf ("Daemon-mode note yet supported.\n");
+		errno = EINVAL;
+		return -1;
+	}
+	s = socket (AF_INET, SOCK_DGRAM, 0);
+	if (s < 0) {
+		printf ("Can't create socket: %s\n", strerror (errno));
+		return -1;
+	}
+	tv.tv_sec = 5;
+	tv.tv_usec = 0;
+	if (setsockopt (s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) {
+		printf ("Can't set socket receive timeout: %s", strerror (errno));
+		return -1;
+	}
+	memset (&myAddr, sizeof myAddr, 0);
+	myAddr.sin_family = AF_INET;
+	myAddr.sin_port = htons (123);
+	myAddr.sin_addr.s_addr = htonl (INADDR_ANY);
+	printf ("Bind socket.\n");
+	if (bind (s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) {
+		printf ("Can't bind socket: %s\n", strerror (errno));
+		return -1;
+	}
+	for (;;) {
+		/*
+		 * If there's no server we just have to wait
+		 * and hope that there's an NTP broadcast
+		 * server out there somewhere.
+		 */
+		if (rtems_bsdnet_ntpserver_count > 0) {
+			memset (&farAddr, sizeof farAddr, 0);
+			farAddr.sin_family = AF_INET;
+			farAddr.sin_port = htons (123);
+			/*
+			 * For now, try only the first server.
+			 */
+			farAddr.sin_addr = rtems_bsdnet_ntpserver[0];
+			memset (&packet, sizeof packet, 0);
+			packet.li_vn_mode = (3 << 3) | 3; /* NTP version 3, client */
+			i = sendto (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, sizeof farAddr);
+			if (i != sizeof packet) {
+				printf ("Can't send: %s\n", strerror (errno));
+				return -1;
+			}
+		}
+		fromlen = sizeof farAddr;
+		i = recvfrom (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, &fromlen);
+		if (i == 0)
+			rtems_panic ("EOF");
+		if (i < 0) {
+			printf ("%d\n", errno);
+			if (errno == EWOULDBLOCK)
+				continue;
+			rtems_panic ("Can't receive: %s", strerror (errno));
+		}
+		if (i >= sizeof packet) {
+			if (processPacket (&packet))
+				return 0;
+		}
+	}
+}
Index: c/src/exec/libnetworking/nfs/bootp_subr.c
===================================================================
--- c/src/exec/libnetworking/nfs/bootp_subr.c	(revision 442d047832f4f5eec31b287ac9ca5707479c9027)
+++ c/src/exec/libnetworking/nfs/bootp_subr.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -731,5 +731,5 @@
       break;
 
-    case 2:    /* Time offset */
+    case 2:
       /* Time offset */
       if (len!=4) 
@@ -749,12 +749,6 @@
       break;
 
-    /*
-     * Some old BOOTP daemons don't support the NTP server (42) tag,
-     * but do support the RFC 868 time server (4) tag.  Cheat here
-     * and assume they mean the same thing.
-     */
-    case 4:
     case 42:
-      /* Time servers */
+      /* NTP servers */
       if (len % 4) 
         panic ("bootpc: time server Len is %d", len);
Index: c/src/exec/libnetworking/rtems/rtems_bsdnet.h
===================================================================
--- c/src/exec/libnetworking/rtems/rtems_bsdnet.h	(revision 442d047832f4f5eec31b287ac9ca5707479c9027)
+++ c/src/exec/libnetworking/rtems/rtems_bsdnet.h	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -136,4 +136,5 @@
 int rtems_bsdnet_initialize_network (void);
 void rtems_bsdnet_do_bootp (void);
+int rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority);
 
 #endif /* _RTEMS_BSDNET_ */
Index: c/src/libnetworking/lib/Makefile.in
===================================================================
--- c/src/libnetworking/lib/Makefile.in	(revision 442d047832f4f5eec31b287ac9ca5707479c9027)
+++ c/src/libnetworking/lib/Makefile.in	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -18,5 +18,5 @@
 
 # C and C++ source names, if any, go here -- minus the .c or .cc
-C_PIECES = getprotoby syslog tftpDriver
+C_PIECES = getprotoby rtems_bsdnet_ntp syslog tftpDriver
 C_FILES = $(C_PIECES:%=%.c)
 C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
Index: c/src/libnetworking/lib/rtems_bsdnet_ntp.c
===================================================================
--- c/src/libnetworking/lib/rtems_bsdnet_ntp.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
+++ c/src/libnetworking/lib/rtems_bsdnet_ntp.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -0,0 +1,160 @@
+/*
+ * Synchronize with an NTP server
+ *
+ * This program may be distributed and used for any purpose.
+ * I ask only that you:
+ *      1. Leave this author information intact.
+ *      2. Document any changes you make.
+ *
+ * W. Eric Norum
+ * Canadian Light Source
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@cls.usask.ca
+ *
+ *  $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <limits.h>
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/error.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/*
+ * RTEMS base: 1988, January 1
+ *  UNIX base: 1970, January 1
+ *   NTP base: 1900, January 1
+ */
+#define UNIX_BASE_TO_NTP_BASE (((70UL*365UL)+17UL) * (24*60*60))
+
+struct timestamp {
+	rtems_unsigned32	integer;
+	rtems_unsigned32	fraction;
+};
+
+struct ntpPacketSmall {
+	rtems_unsigned8		li_vn_mode;
+	rtems_unsigned8		stratum;
+	rtems_signed8		poll_interval;
+	rtems_signed8		precision;
+	rtems_signed32		root_delay;
+	rtems_signed32		root_dispersion;
+	char			reference_identifier[4];
+	struct timestamp	reference_timestamp;
+	struct timestamp	originate_timestamp;
+	struct timestamp	receive_timestamp;
+	struct timestamp	transmit_timestamp;
+};
+
+struct ntpPacket {
+	struct ntpPacketSmall	ntp;
+	char			authenticator[96];
+};
+
+static int
+processPacket (struct ntpPacketSmall *p)
+{
+	time_t tbuf;
+	struct tm *lt;
+	rtems_time_of_day rt;
+	rtems_interval ticks_per_second;
+
+	if (((p->li_vn_mode & (0x7 << 3)) != (3 << 3))
+	 || ((p->transmit_timestamp.integer == 0) && (p->transmit_timestamp.fraction == 0)))
+		return 0;
+	rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+	tbuf = ntohl (p->transmit_timestamp.integer) - UNIX_BASE_TO_NTP_BASE - rtems_bsdnet_timeoffset;
+	lt = gmtime (&tbuf);
+	rt.year = lt->tm_year + 1900;
+	rt.month = lt->tm_mon + 1;
+	rt.day = lt->tm_mday;
+	rt.hour = lt->tm_hour;
+	rt.minute = lt->tm_min;
+	rt.second = lt->tm_sec;
+	rt.ticks = ntohl (p->transmit_timestamp.fraction) / (ULONG_MAX / ticks_per_second);
+	if (rt.ticks >= ticks_per_second)
+		rt.ticks = ticks_per_second - 1;
+	rtems_clock_set (&rt);
+	return 1;
+}
+
+int
+rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority)
+{
+	int s;
+	int i;
+	static struct sockaddr_in myAddr, farAddr;
+	int fromlen;
+	struct ntpPacketSmall packet;
+	struct timeval tv;
+
+	if (interval != 0) {
+		printf ("Daemon-mode note yet supported.\n");
+		errno = EINVAL;
+		return -1;
+	}
+	s = socket (AF_INET, SOCK_DGRAM, 0);
+	if (s < 0) {
+		printf ("Can't create socket: %s\n", strerror (errno));
+		return -1;
+	}
+	tv.tv_sec = 5;
+	tv.tv_usec = 0;
+	if (setsockopt (s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) {
+		printf ("Can't set socket receive timeout: %s", strerror (errno));
+		return -1;
+	}
+	memset (&myAddr, sizeof myAddr, 0);
+	myAddr.sin_family = AF_INET;
+	myAddr.sin_port = htons (123);
+	myAddr.sin_addr.s_addr = htonl (INADDR_ANY);
+	printf ("Bind socket.\n");
+	if (bind (s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) {
+		printf ("Can't bind socket: %s\n", strerror (errno));
+		return -1;
+	}
+	for (;;) {
+		/*
+		 * If there's no server we just have to wait
+		 * and hope that there's an NTP broadcast
+		 * server out there somewhere.
+		 */
+		if (rtems_bsdnet_ntpserver_count > 0) {
+			memset (&farAddr, sizeof farAddr, 0);
+			farAddr.sin_family = AF_INET;
+			farAddr.sin_port = htons (123);
+			/*
+			 * For now, try only the first server.
+			 */
+			farAddr.sin_addr = rtems_bsdnet_ntpserver[0];
+			memset (&packet, sizeof packet, 0);
+			packet.li_vn_mode = (3 << 3) | 3; /* NTP version 3, client */
+			i = sendto (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, sizeof farAddr);
+			if (i != sizeof packet) {
+				printf ("Can't send: %s\n", strerror (errno));
+				return -1;
+			}
+		}
+		fromlen = sizeof farAddr;
+		i = recvfrom (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, &fromlen);
+		if (i == 0)
+			rtems_panic ("EOF");
+		if (i < 0) {
+			printf ("%d\n", errno);
+			if (errno == EWOULDBLOCK)
+				continue;
+			rtems_panic ("Can't receive: %s", strerror (errno));
+		}
+		if (i >= sizeof packet) {
+			if (processPacket (&packet))
+				return 0;
+		}
+	}
+}
Index: c/src/libnetworking/nfs/bootp_subr.c
===================================================================
--- c/src/libnetworking/nfs/bootp_subr.c	(revision 442d047832f4f5eec31b287ac9ca5707479c9027)
+++ c/src/libnetworking/nfs/bootp_subr.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -731,5 +731,5 @@
       break;
 
-    case 2:    /* Time offset */
+    case 2:
       /* Time offset */
       if (len!=4) 
@@ -749,12 +749,6 @@
       break;
 
-    /*
-     * Some old BOOTP daemons don't support the NTP server (42) tag,
-     * but do support the RFC 868 time server (4) tag.  Cheat here
-     * and assume they mean the same thing.
-     */
-    case 4:
     case 42:
-      /* Time servers */
+      /* NTP servers */
       if (len % 4) 
         panic ("bootpc: time server Len is %d", len);
Index: c/src/libnetworking/rtems/rtems_bsdnet.h
===================================================================
--- c/src/libnetworking/rtems/rtems_bsdnet.h	(revision 442d047832f4f5eec31b287ac9ca5707479c9027)
+++ c/src/libnetworking/rtems/rtems_bsdnet.h	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -136,4 +136,5 @@
 int rtems_bsdnet_initialize_network (void);
 void rtems_bsdnet_do_bootp (void);
+int rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority);
 
 #endif /* _RTEMS_BSDNET_ */
Index: cpukit/libnetworking/lib/rtems_bsdnet_ntp.c
===================================================================
--- cpukit/libnetworking/lib/rtems_bsdnet_ntp.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
+++ cpukit/libnetworking/lib/rtems_bsdnet_ntp.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -0,0 +1,160 @@
+/*
+ * Synchronize with an NTP server
+ *
+ * This program may be distributed and used for any purpose.
+ * I ask only that you:
+ *      1. Leave this author information intact.
+ *      2. Document any changes you make.
+ *
+ * W. Eric Norum
+ * Canadian Light Source
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@cls.usask.ca
+ *
+ *  $Id$
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <limits.h>
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/error.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/*
+ * RTEMS base: 1988, January 1
+ *  UNIX base: 1970, January 1
+ *   NTP base: 1900, January 1
+ */
+#define UNIX_BASE_TO_NTP_BASE (((70UL*365UL)+17UL) * (24*60*60))
+
+struct timestamp {
+	rtems_unsigned32	integer;
+	rtems_unsigned32	fraction;
+};
+
+struct ntpPacketSmall {
+	rtems_unsigned8		li_vn_mode;
+	rtems_unsigned8		stratum;
+	rtems_signed8		poll_interval;
+	rtems_signed8		precision;
+	rtems_signed32		root_delay;
+	rtems_signed32		root_dispersion;
+	char			reference_identifier[4];
+	struct timestamp	reference_timestamp;
+	struct timestamp	originate_timestamp;
+	struct timestamp	receive_timestamp;
+	struct timestamp	transmit_timestamp;
+};
+
+struct ntpPacket {
+	struct ntpPacketSmall	ntp;
+	char			authenticator[96];
+};
+
+static int
+processPacket (struct ntpPacketSmall *p)
+{
+	time_t tbuf;
+	struct tm *lt;
+	rtems_time_of_day rt;
+	rtems_interval ticks_per_second;
+
+	if (((p->li_vn_mode & (0x7 << 3)) != (3 << 3))
+	 || ((p->transmit_timestamp.integer == 0) && (p->transmit_timestamp.fraction == 0)))
+		return 0;
+	rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+	tbuf = ntohl (p->transmit_timestamp.integer) - UNIX_BASE_TO_NTP_BASE - rtems_bsdnet_timeoffset;
+	lt = gmtime (&tbuf);
+	rt.year = lt->tm_year + 1900;
+	rt.month = lt->tm_mon + 1;
+	rt.day = lt->tm_mday;
+	rt.hour = lt->tm_hour;
+	rt.minute = lt->tm_min;
+	rt.second = lt->tm_sec;
+	rt.ticks = ntohl (p->transmit_timestamp.fraction) / (ULONG_MAX / ticks_per_second);
+	if (rt.ticks >= ticks_per_second)
+		rt.ticks = ticks_per_second - 1;
+	rtems_clock_set (&rt);
+	return 1;
+}
+
+int
+rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority)
+{
+	int s;
+	int i;
+	static struct sockaddr_in myAddr, farAddr;
+	int fromlen;
+	struct ntpPacketSmall packet;
+	struct timeval tv;
+
+	if (interval != 0) {
+		printf ("Daemon-mode note yet supported.\n");
+		errno = EINVAL;
+		return -1;
+	}
+	s = socket (AF_INET, SOCK_DGRAM, 0);
+	if (s < 0) {
+		printf ("Can't create socket: %s\n", strerror (errno));
+		return -1;
+	}
+	tv.tv_sec = 5;
+	tv.tv_usec = 0;
+	if (setsockopt (s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) {
+		printf ("Can't set socket receive timeout: %s", strerror (errno));
+		return -1;
+	}
+	memset (&myAddr, sizeof myAddr, 0);
+	myAddr.sin_family = AF_INET;
+	myAddr.sin_port = htons (123);
+	myAddr.sin_addr.s_addr = htonl (INADDR_ANY);
+	printf ("Bind socket.\n");
+	if (bind (s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) {
+		printf ("Can't bind socket: %s\n", strerror (errno));
+		return -1;
+	}
+	for (;;) {
+		/*
+		 * If there's no server we just have to wait
+		 * and hope that there's an NTP broadcast
+		 * server out there somewhere.
+		 */
+		if (rtems_bsdnet_ntpserver_count > 0) {
+			memset (&farAddr, sizeof farAddr, 0);
+			farAddr.sin_family = AF_INET;
+			farAddr.sin_port = htons (123);
+			/*
+			 * For now, try only the first server.
+			 */
+			farAddr.sin_addr = rtems_bsdnet_ntpserver[0];
+			memset (&packet, sizeof packet, 0);
+			packet.li_vn_mode = (3 << 3) | 3; /* NTP version 3, client */
+			i = sendto (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, sizeof farAddr);
+			if (i != sizeof packet) {
+				printf ("Can't send: %s\n", strerror (errno));
+				return -1;
+			}
+		}
+		fromlen = sizeof farAddr;
+		i = recvfrom (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, &fromlen);
+		if (i == 0)
+			rtems_panic ("EOF");
+		if (i < 0) {
+			printf ("%d\n", errno);
+			if (errno == EWOULDBLOCK)
+				continue;
+			rtems_panic ("Can't receive: %s", strerror (errno));
+		}
+		if (i >= sizeof packet) {
+			if (processPacket (&packet))
+				return 0;
+		}
+	}
+}
Index: cpukit/libnetworking/nfs/bootp_subr.c
===================================================================
--- cpukit/libnetworking/nfs/bootp_subr.c	(revision 442d047832f4f5eec31b287ac9ca5707479c9027)
+++ cpukit/libnetworking/nfs/bootp_subr.c	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -731,5 +731,5 @@
       break;
 
-    case 2:    /* Time offset */
+    case 2:
       /* Time offset */
       if (len!=4) 
@@ -749,12 +749,6 @@
       break;
 
-    /*
-     * Some old BOOTP daemons don't support the NTP server (42) tag,
-     * but do support the RFC 868 time server (4) tag.  Cheat here
-     * and assume they mean the same thing.
-     */
-    case 4:
     case 42:
-      /* Time servers */
+      /* NTP servers */
       if (len % 4) 
         panic ("bootpc: time server Len is %d", len);
Index: cpukit/libnetworking/rtems/rtems_bsdnet.h
===================================================================
--- cpukit/libnetworking/rtems/rtems_bsdnet.h	(revision 442d047832f4f5eec31b287ac9ca5707479c9027)
+++ cpukit/libnetworking/rtems/rtems_bsdnet.h	(revision cbccd37599bb2a6007c29493ed05f02a0306d4da)
@@ -136,4 +136,5 @@
 int rtems_bsdnet_initialize_network (void);
 void rtems_bsdnet_do_bootp (void);
+int rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority);
 
 #endif /* _RTEMS_BSDNET_ */
