diff --git a/Net/Makefile b/Net/Makefile
index 3d73f282d..fa0ab16e9 100644
--- a/Net/Makefile
+++ b/Net/Makefile
@@ -30,6 +30,7 @@ objects = \
MailRecipient MailMessage MailStream SMTPClientSession POP3ClientSession \
RawSocket RawSocketImpl ICMPClient ICMPEventArgs ICMPPacket ICMPPacketImpl \
ICMPSocket ICMPSocketImpl ICMPv4PacketImpl \
+ NTPClient NTPEventArgs NTPPacket \
RemoteSyslogChannel RemoteSyslogListener SMTPChannel \
WebSocket WebSocketImpl
diff --git a/Net/Net_vs100.vcxproj b/Net/Net_vs100.vcxproj
index ce6fad993..283172ff8 100644
--- a/Net/Net_vs100.vcxproj
+++ b/Net/Net_vs100.vcxproj
@@ -274,6 +274,9 @@
+
+
+
@@ -376,6 +379,9 @@
+
+
+
diff --git a/Net/Net_vs100.vcxproj.filters b/Net/Net_vs100.vcxproj.filters
index b8cdb3188..e5cb79e4e 100644
--- a/Net/Net_vs100.vcxproj.filters
+++ b/Net/Net_vs100.vcxproj.filters
@@ -127,6 +127,15 @@
{9e8d3dd2-8950-4437-b83d-0f5c2acdf755}
+
+ {da44ddca-d7c4-49d7-9d2d-eae118575059}
+
+
+ {b1bc5e82-a8e3-4c3c-9bef-f5ebc71a5ffc}
+
+
+ {ef2b98c6-9300-404b-b922-f1d79bca1d6b}
+
@@ -429,6 +438,15 @@
NetCore\Header Files
+
+ NTPClient\Header Files
+
+
+ NTPClient\Header Files
+
+
+ NTPClient\Header Files
+
@@ -713,6 +731,15 @@
NetCore\Source Files
+
+ NTPClient\Source Files
+
+
+ NTPClient\Source Files
+
+
+ NTPClient\Source Files
+
diff --git a/Net/include/Poco/Net/NTPClient.h b/Net/include/Poco/Net/NTPClient.h
new file mode 100644
index 000000000..cd7dcb7da
--- /dev/null
+++ b/Net/include/Poco/Net/NTPClient.h
@@ -0,0 +1,86 @@
+//
+// NTPClient.h
+//
+// $Id: //poco/1.4/Net/include/Poco/Net/NTPClient.h#1 $
+//
+// Library: Net
+// Package: NTP
+// Module: NTPClient
+//
+// Definition of the NTPClient class.
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#ifndef Net_NTPClient_INCLUDED
+#define Net_NTPClient_INCLUDED
+
+
+#include "Poco/Net/Net.h"
+#include "Poco/Net/NTPEventArgs.h"
+#include "Poco/Net/SocketAddress.h"
+#include "Poco/BasicEvent.h"
+
+
+namespace Poco {
+namespace Net {
+
+
+class Net_API NTPClient
+ /// This class provides NTP (Network Time Protocol) client functionality.
+{
+public:
+ mutable Poco::BasicEvent response;
+
+ explicit NTPClient(IPAddress::Family family, int timeout = 3000000);
+ /// Creates an NTP client.
+
+ ~NTPClient();
+ /// Destroys the NTP client.
+
+ int request(SocketAddress& address) const;
+ /// Request the time from the server at address.
+ /// Notifications are posted for events.
+ ///
+ /// Returns the number of valid replies.
+
+ int request(const std::string& address) const;
+ /// Request the time from the server at address.
+ /// Notifications are posted for events.
+ ///
+ /// Returns the number of valid replies.
+
+private:
+ mutable IPAddress::Family _family;
+ int _timeout;
+};
+
+
+} } // namespace Poco::Net
+
+
+#endif // Net_NTPClient_INCLUDED
diff --git a/Net/include/Poco/Net/NTPEventArgs.h b/Net/include/Poco/Net/NTPEventArgs.h
new file mode 100644
index 000000000..c403c8702
--- /dev/null
+++ b/Net/include/Poco/Net/NTPEventArgs.h
@@ -0,0 +1,106 @@
+//
+// NTPEventArgs.h
+//
+// $Id: //poco/1.4/Net/include/Poco/Net/NTPEventArgs.h#1 $
+//
+// Library: Net
+// Package: NTP
+// Module: NTPEventArgs
+//
+// Definition of NTPEventArgs.
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#ifndef Net_NTPEventArgs_INCLUDED
+#define Net_NTPEventArgs_INCLUDED
+
+
+#include "Poco/Net/Net.h"
+#include "Poco/Net/SocketAddress.h"
+#include "Poco/Net/NTPPacket.h"
+
+
+namespace Poco {
+namespace Net {
+
+
+class Net_API NTPEventArgs
+ /// The purpose of the NTPEventArgs class is to be used as template parameter
+ /// to instantiate event members in NTPClient class.
+ /// When clients register for an event notification, the reference to the class is
+ /// passed to the handler function to provide information about the event.
+{
+public:
+ NTPEventArgs(const SocketAddress& address);
+ /// Creates NTPEventArgs.
+
+ virtual ~NTPEventArgs();
+ /// Destroys NTPEventArgs.
+
+ std::string hostName() const;
+ /// Tries to resolve the target IP address into host name.
+ /// If unsuccessful, all exceptions are silently ignored and
+ /// the IP address is returned.
+
+ std::string hostAddress() const;
+ /// Returns the target IP address.
+
+ const NTPPacket &packet();
+ /// Returns the NTP packet.
+
+private:
+ NTPEventArgs();
+
+ void setPacket(NTPPacket &packet);
+
+ SocketAddress _address;
+ NTPPacket _packet;
+
+ friend class NTPClient;
+};
+
+
+//
+// inlines
+//
+inline const NTPPacket &NTPEventArgs::packet()
+{
+ return _packet;
+}
+
+
+inline void NTPEventArgs::setPacket(NTPPacket &packet)
+{
+ _packet = packet;
+}
+
+
+} } // namespace Poco::Net
+
+
+#endif
diff --git a/Net/include/Poco/Net/NTPPacket.h b/Net/include/Poco/Net/NTPPacket.h
new file mode 100644
index 000000000..b861a9760
--- /dev/null
+++ b/Net/include/Poco/Net/NTPPacket.h
@@ -0,0 +1,229 @@
+//
+// NTPPacket.h
+//
+// $Id: //poco/1.4/Net/include/Poco/Net/NTPPacket.h#1 $
+//
+// Library: Net
+// Package: NTP
+// Module: NTPPacket
+//
+// Definition of the NTPPacket class.
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#ifndef Net_NTPPacket_INCLUDED
+#define Net_NTPPacket_INCLUDED
+
+
+#include "Poco/Foundation.h"
+#include "Poco/Net/Net.h"
+#include "Poco/Timestamp.h"
+
+namespace Poco {
+namespace Net {
+
+
+class Net_API NTPPacket
+ /// This class is the NTP packet abstraction.
+{
+public:
+ NTPPacket();
+ /// Creates an NTPPacket.
+
+ NTPPacket(Poco::UInt8 *packet);
+ /// Creates an NTPPacket.
+ ///
+ /// Assumed to have at least 48 bytes.
+
+ ~NTPPacket();
+ /// Destroys the NTPPacket.
+
+ void packet(Poco::UInt8 *packet) const;
+ /// Returns the NTP packet.
+ ///
+ /// Assumed to have at least 48 bytes.
+
+ void setPacket(Poco::UInt8 *packet);
+ /// Returns the NTP packet.
+ ///
+ /// Assumed to have exactly 48 bytes.
+
+ Poco::Int8 leapIndicator() const;
+ /// Returns the leap indicator.
+
+ Poco::Int8 version() const;
+ /// Returns the version.
+
+ Poco::Int8 mode() const;
+ /// Returns the mode.
+
+ Poco::Int8 stratum() const;
+ /// Returns the stratum.
+
+ Poco::Int8 pool() const;
+ /// Returns the pool.
+
+ Poco::Int8 precision() const;
+ /// Returns the precision
+
+ Poco::Int32 rootDelay() const;
+ /// Returns the root delay
+
+ Poco::Int32 rootDispersion() const;
+ /// Returns the root dispersion
+
+ Poco::Int32 referenceId() const;
+ /// Returns the reference id
+
+ Poco::Int64 referenceTimestamp() const;
+ /// Returns the reference timestamp
+
+ Poco::Int64 originateTimestamp() const;
+ /// Returns the originate timestamp
+
+ Poco::Int64 receiveTimestamp() const;
+ /// Returns the receive timestamp
+
+ Poco::Int64 transmitTimestamp() const;
+ /// Returns the transmit timestamp
+
+ Poco::Timestamp referenceTime() const;
+ /// Returns the reference time
+
+ Poco::Timestamp originateTime() const;
+ /// Returns the originate time
+
+ Poco::Timestamp receiveTime() const;
+ /// Returns the receive time
+
+ Poco::Timestamp transmitTime() const;
+ /// Returns the transmit time
+private:
+ Poco::Timestamp convertTime(Poco::Int64 tm) const;
+
+ Poco::Int8 _leapIndicator;
+ Poco::Int8 _version;
+ Poco::Int8 _mode;
+ Poco::Int8 _stratum;
+ Poco::Int8 _pool;
+ Poco::Int8 _precision;
+ Poco::Int32 _rootDelay;
+ Poco::Int32 _rootDispersion;
+ Poco::Int32 _referenceId;
+ Poco::Int64 _referenceTimestamp;
+ Poco::Int64 _originateTimestamp;
+ Poco::Int64 _receiveTimestamp;
+ Poco::Int64 _transmitTimestamp;
+};
+
+
+//
+// inlines
+//
+inline Poco::Int8 NTPPacket::leapIndicator() const
+{
+ return _leapIndicator;
+}
+
+
+inline Poco::Int8 NTPPacket::version() const
+{
+ return _version;
+}
+
+
+inline Poco::Int8 NTPPacket::mode() const
+{
+ return _mode;
+}
+
+
+inline Poco::Int8 NTPPacket::stratum() const
+{
+ return _stratum;
+}
+
+
+inline Poco::Int8 NTPPacket::pool() const
+{
+ return _pool;
+}
+
+
+inline Poco::Int8 NTPPacket::precision() const
+{
+ return _precision;
+}
+
+
+inline Poco::Int32 NTPPacket::rootDelay() const
+{
+ return _rootDelay;
+}
+
+
+inline Poco::Int32 NTPPacket::rootDispersion() const
+{
+ return _rootDispersion;
+}
+
+
+inline Poco::Int32 NTPPacket::referenceId() const
+{
+ return _referenceId;
+}
+
+
+inline Poco::Int64 NTPPacket::referenceTimestamp() const
+{
+ return _referenceTimestamp;
+}
+
+
+inline Poco::Int64 NTPPacket::originateTimestamp() const
+{
+ return _originateTimestamp;
+}
+
+
+inline Poco::Int64 NTPPacket::receiveTimestamp() const
+{
+ return _receiveTimestamp;
+}
+
+
+inline Poco::Int64 NTPPacket::transmitTimestamp() const
+{
+ return _transmitTimestamp;
+}
+
+
+} } // namespace Poco::Net
+
+
+#endif // Net_NTPPacket_INCLUDED
diff --git a/Net/include/Poco/Net/NetException.h b/Net/include/Poco/Net/NetException.h
index f4480e12a..471df7efe 100644
--- a/Net/include/Poco/Net/NetException.h
+++ b/Net/include/Poco/Net/NetException.h
@@ -69,6 +69,7 @@ POCO_DECLARE_EXCEPTION(Net_API, FTPException, NetException)
POCO_DECLARE_EXCEPTION(Net_API, SMTPException, NetException)
POCO_DECLARE_EXCEPTION(Net_API, POP3Exception, NetException)
POCO_DECLARE_EXCEPTION(Net_API, ICMPException, NetException)
+POCO_DECLARE_EXCEPTION(Net_API, NTPException, NetException)
POCO_DECLARE_EXCEPTION(Net_API, HTMLFormException, NetException)
POCO_DECLARE_EXCEPTION(Net_API, WebSocketException, NetException)
POCO_DECLARE_EXCEPTION(Net_API, UnsupportedFamilyException, NetException)
diff --git a/Net/src/NTPClient.cpp b/Net/src/NTPClient.cpp
new file mode 100644
index 000000000..a1bece389
--- /dev/null
+++ b/Net/src/NTPClient.cpp
@@ -0,0 +1,109 @@
+//
+// NTPClient.cpp
+//
+// $Id: //poco/1.4/Net/src/NTPClient.cpp#1 $
+//
+// Library: Net
+// Package: NTP
+// Module: NTPClient
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#include "Poco/Net/SocketAddress.h"
+#include "Poco/Net/NTPClient.h"
+#include "Poco/Net/NTPPacket.h"
+#include "Poco/Net/DatagramSocket.h"
+#include "Poco/Net/NetException.h"
+
+
+using Poco::TimeoutException;
+
+
+namespace Poco {
+namespace Net {
+
+
+NTPClient::NTPClient(IPAddress::Family family, int timeout):
+ _family(family), _timeout(timeout)
+{
+}
+
+
+NTPClient::~NTPClient()
+{
+}
+
+
+int NTPClient::request(const std::string& address) const
+{
+ SocketAddress addr(address, 123);
+ return request(addr);
+}
+
+
+int NTPClient::request(SocketAddress& address) const
+{
+ Poco::Net::SocketAddress sa;
+ DatagramSocket ntpSocket(_family);
+ ntpSocket.setReceiveTimeout(_timeout);
+ ntpSocket.bind(sa);
+
+ SocketAddress returnAddress;
+
+ NTPEventArgs eventArgs(address);
+
+ NTPPacket packet;
+ Poco::UInt8 p[1024];
+ packet.packet(&p[0]);
+
+ ntpSocket.sendTo(p, 48, address);
+
+ int received = 0;
+ try
+ {
+ Poco::Net::SocketAddress sender;
+ int n = ntpSocket.receiveFrom(p, sizeof(p)-1, sender);
+
+ if (n < 48) // NTP packet must have at least 48 bytes
+ throw Poco::Net::NTPException("Invalid response received");
+
+ packet.setPacket(p);
+ eventArgs.setPacket(packet);
+ ++received;
+ response.notify(this, eventArgs);
+ }
+ catch (Poco::TimeoutException &)
+ {
+ // ignore
+ }
+
+ return received;
+}
+
+
+} } // namespace Poco::Net
diff --git a/Net/src/NTPEventArgs.cpp b/Net/src/NTPEventArgs.cpp
new file mode 100644
index 000000000..37cae3a7a
--- /dev/null
+++ b/Net/src/NTPEventArgs.cpp
@@ -0,0 +1,93 @@
+//
+// NTPEventArgs.cpp
+//
+// $Id: //poco/1.4/Net/src/NTPEventArgs.cpp#1 $
+//
+// Library: Net
+// Package: NTP
+// Module: NTPEventArgs
+//
+// Implementation of NTPEventArgs
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#include "Poco/Net/NTPEventArgs.h"
+#include "Poco/Net/SocketAddress.h"
+#include "Poco/Net/DNS.h"
+#include "Poco/Exception.h"
+#include "Poco/Net/NetException.h"
+
+
+using Poco::IOException;
+using Poco::InvalidArgumentException;
+
+
+namespace Poco {
+namespace Net {
+
+
+NTPEventArgs::NTPEventArgs(const SocketAddress& address):
+ _address(address), _packet()
+{
+}
+
+
+NTPEventArgs::~NTPEventArgs()
+{
+}
+
+
+std::string NTPEventArgs::hostName() const
+{
+ try
+ {
+ return DNS::resolve(_address.host().toString()).name();
+ }
+ catch (HostNotFoundException&)
+ {
+ }
+ catch (NoAddressFoundException&)
+ {
+ }
+ catch (DNSException&)
+ {
+ }
+ catch (IOException&)
+ {
+ }
+ return _address.host().toString();
+}
+
+
+std::string NTPEventArgs::hostAddress() const
+{
+ return _address.host().toString();
+}
+
+
+} } // namespace Poco::Net
diff --git a/Net/src/NTPPacket.cpp b/Net/src/NTPPacket.cpp
new file mode 100644
index 000000000..01e05aa4a
--- /dev/null
+++ b/Net/src/NTPPacket.cpp
@@ -0,0 +1,170 @@
+//
+// NTPPacket.cpp
+//
+// $Id: //poco/1.4/Net/src/NTPPacket.cpp#2 $
+//
+// Library: Net
+// Package: NTP
+// Module: NTPPacket
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#include "Poco/Net/NTPPacket.h"
+#include "Poco/Net/NetException.h"
+#include "Poco/Timestamp.h"
+#include "Poco/ByteOrder.h"
+
+
+namespace Poco {
+namespace Net {
+
+#pragma pack(push,1)
+typedef struct _NTPPacketData {
+ Poco::Int8 mode:3;
+ Poco::Int8 vn:3;
+ Poco::Int8 li:2;
+ Poco::Int8 stratum;
+ Poco::Int8 pool;
+ Poco::Int8 prec;
+ Poco::Int32 rootdelay;
+ Poco::Int32 rootdisp;
+ Poco::Int32 refid;
+ Poco::Int64 rts;
+ Poco::Int64 ots;
+ Poco::Int64 vts;
+ Poco::Int64 tts;
+} NTPPacketData;
+#pragma pack(pop)
+
+
+NTPPacket::NTPPacket() :
+ // the next 3 fields must be in reverse order from spec
+ _leapIndicator(3),
+ _version(4),
+ _mode(3),
+
+ _stratum(0),
+ _pool(6),
+ _precision(-18),
+ _rootDelay(0),
+ _rootDispersion(0),
+ _referenceId(0),
+ _referenceTimestamp(0),
+ _receiveTimestamp(0),
+ _transmitTimestamp(0)
+{
+ Poco::Timestamp ts;
+ _originateTimestamp = ts.utcTime();
+}
+
+
+NTPPacket::NTPPacket(Poco::UInt8 *packet)
+{
+ setPacket(packet);
+}
+
+
+NTPPacket::~NTPPacket()
+{
+}
+
+
+void NTPPacket::packet(Poco::UInt8 *packet) const
+{
+ NTPPacketData *p = (NTPPacketData*)packet;
+
+ p->li = _leapIndicator;
+ p->vn = _version;
+ p->mode = _mode;
+ p->stratum = _stratum;
+ p->pool = _pool;
+ p->prec = _precision;
+ p->rootdelay = Poco::ByteOrder::toNetwork(_rootDelay);
+ p->rootdisp = Poco::ByteOrder::toNetwork(_rootDispersion);
+ p->refid = Poco::ByteOrder::toNetwork(_referenceId);
+ p->rts = Poco::ByteOrder::toNetwork(_referenceTimestamp);
+ p->ots = Poco::ByteOrder::toNetwork(_originateTimestamp);
+ p->vts = Poco::ByteOrder::toNetwork(_receiveTimestamp);
+ p->tts = Poco::ByteOrder::toNetwork(_transmitTimestamp);
+}
+
+
+void NTPPacket::setPacket(Poco::UInt8 *packet)
+{
+ NTPPacketData *p = (NTPPacketData*)packet;
+
+ _leapIndicator = p->li;
+ _version = p->vn;
+ _mode = p->mode;
+ _stratum = p->stratum;
+ _pool = p->pool;
+ _precision = p->prec;
+ _rootDelay = Poco::ByteOrder::fromNetwork(p->rootdelay);
+ _rootDispersion = Poco::ByteOrder::fromNetwork(p->rootdisp);
+ _referenceId = Poco::ByteOrder::fromNetwork(p->refid);
+ _referenceTimestamp = Poco::ByteOrder::fromNetwork(p->rts);
+ _originateTimestamp = Poco::ByteOrder::fromNetwork(p->ots);
+ _receiveTimestamp = Poco::ByteOrder::fromNetwork(p->vts);
+ _transmitTimestamp = Poco::ByteOrder::fromNetwork(p->tts);
+}
+
+
+Poco::Timestamp NTPPacket::referenceTime() const
+{
+ return convertTime(_referenceTimestamp);
+}
+
+
+Poco::Timestamp NTPPacket::originateTime() const
+{
+ return convertTime(_originateTimestamp);
+}
+
+
+Poco::Timestamp NTPPacket::receiveTime() const
+{
+ return convertTime(_receiveTimestamp);
+}
+
+
+Poco::Timestamp NTPPacket::transmitTime() const
+{
+ return convertTime(_transmitTimestamp);
+}
+
+
+Poco::Timestamp NTPPacket::convertTime(Poco::Int64 tm) const
+{
+ const unsigned long seventyYears = 2208988800UL;
+ Poco::UInt32 secsSince1900 = UInt32(Poco::ByteOrder::toLittleEndian(tm) >> 32);
+ unsigned long epoch = secsSince1900 - seventyYears;
+ return Poco::Timestamp::fromEpochTime(epoch);
+}
+
+
+} } // namespace Poco::Net
diff --git a/Net/src/NetException.cpp b/Net/src/NetException.cpp
index 29299870c..fcba36c3e 100644
--- a/Net/src/NetException.cpp
+++ b/Net/src/NetException.cpp
@@ -66,6 +66,7 @@ POCO_IMPLEMENT_EXCEPTION(FTPException, NetException, "FTP Exception")
POCO_IMPLEMENT_EXCEPTION(SMTPException, NetException, "SMTP Exception")
POCO_IMPLEMENT_EXCEPTION(POP3Exception, NetException, "POP3 Exception")
POCO_IMPLEMENT_EXCEPTION(ICMPException, NetException, "ICMP Exception")
+POCO_IMPLEMENT_EXCEPTION(NTPException, NetException, "NTP Exception")
POCO_IMPLEMENT_EXCEPTION(HTMLFormException, NetException, "HTML Form Exception")
POCO_IMPLEMENT_EXCEPTION(WebSocketException, NetException, "WebSocket Exception")
POCO_IMPLEMENT_EXCEPTION(UnsupportedFamilyException, NetException, "Unknown or unsupported socket family.")
diff --git a/Net/testsuite/Makefile b/Net/testsuite/Makefile
index dabcca0c4..0bb0d96fe 100644
--- a/Net/testsuite/Makefile
+++ b/Net/testsuite/Makefile
@@ -25,6 +25,7 @@ objects = \
MailTestSuite MailMessageTest MailStreamTest \
SMTPClientSessionTest POP3ClientSessionTest \
RawSocketTest ICMPClientTest ICMPSocketTest ICMPClientTestSuite \
+ NTPClientTest NTPClientTestSuite \
WebSocketTest WebSocketTestSuite \
SyslogTest
diff --git a/Net/testsuite/TestSuite_vs100.vcxproj b/Net/testsuite/TestSuite_vs100.vcxproj
index 94bdabd5e..02d96c04b 100644
--- a/Net/testsuite/TestSuite_vs100.vcxproj
+++ b/Net/testsuite/TestSuite_vs100.vcxproj
@@ -304,6 +304,8 @@
+
+
@@ -361,6 +363,8 @@
+
+
diff --git a/Net/testsuite/TestSuite_vs100.vcxproj.filters b/Net/testsuite/TestSuite_vs100.vcxproj.filters
index 5059d8153..efb189120 100644
--- a/Net/testsuite/TestSuite_vs100.vcxproj.filters
+++ b/Net/testsuite/TestSuite_vs100.vcxproj.filters
@@ -142,6 +142,15 @@
{713c4782-210c-4445-a809-8f69cb1321e0}
+
+ {ae1526ee-c26e-44a9-87cd-a93a4f53d767}
+
+
+ {27258d95-fc91-49f5-91f6-394bbc22ab87}
+
+
+ {c3807303-d9a4-4f19-bde7-352357a270e3}
+
@@ -309,6 +318,12 @@
WebSocket\Header Files
+
+ NTPClient\HeaderFiles
+
+
+ NTPClient\HeaderFiles
+
@@ -479,5 +494,11 @@
WebSocket\Source Files
+
+ NTPClient\Source Files
+
+
+ NTPClient\Source Files
+
\ No newline at end of file
diff --git a/Net/testsuite/src/NTPClientTest.cpp b/Net/testsuite/src/NTPClientTest.cpp
new file mode 100644
index 000000000..6a8a352d9
--- /dev/null
+++ b/Net/testsuite/src/NTPClientTest.cpp
@@ -0,0 +1,104 @@
+//
+// NTPClientTest.cpp
+//
+// $Id: //poco/1.4/Net/testsuite/src/NTPClientTest.cpp#1 $
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#include "NTPClientTest.h"
+#include "CppUnit/TestCaller.h"
+#include "CppUnit/TestSuite.h"
+#include "Poco/Net/NTPClient.h"
+#include "Poco/Net/NTPEventArgs.h"
+#include "Poco/Net/SocketAddress.h"
+#include "Poco/Net/NetException.h"
+#include "Poco/AutoPtr.h"
+#include "Poco/Delegate.h"
+#include "Poco/DateTimeFormatter.h"
+#include "Poco/DateTimeFormat.h"
+#include
+#include
+
+
+using Poco::Net::NTPClient;
+using Poco::Net::NTPEventArgs;
+using Poco::Net::SocketAddress;
+using Poco::Net::IPAddress;
+using Poco::Net::HostNotFoundException;
+using Poco::Delegate;
+using Poco::AutoPtr;
+
+
+NTPClientTest::NTPClientTest(const std::string& name):
+ CppUnit::TestCase(name),
+ _ntpClient(IPAddress::IPv4)
+{
+}
+
+
+NTPClientTest::~NTPClientTest()
+{
+}
+
+
+void NTPClientTest::testTimeSync()
+{
+ assert(_ntpClient.request("pool.ntp.br") > 0);
+}
+
+
+void NTPClientTest::setUp()
+{
+ _ntpClient.response += Delegate(this, &NTPClientTest::onResponse);
+}
+
+
+void NTPClientTest::tearDown()
+{
+ _ntpClient.response -= Delegate(this, &NTPClientTest::onResponse);
+}
+
+
+void NTPClientTest::onResponse(const void* pSender, NTPEventArgs& args)
+{
+ std::ostringstream os;
+ os << std::endl << "Received from " << args.hostName() << " [" << args.hostAddress() << "] with "
+ << Poco::DateTimeFormatter::format(args.packet().referenceTime(), Poco::DateTimeFormat::ISO8601_FORMAT) << " reference typestamp"
+ << std::endl;
+ std::cout << os.str() << std::endl;
+}
+
+
+CppUnit::Test* NTPClientTest::suite()
+{
+ CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NTPClientTest");
+
+ CppUnit_addTest(pSuite, NTPClientTest, testTimeSync);
+
+ return pSuite;
+}
diff --git a/Net/testsuite/src/NTPClientTest.h b/Net/testsuite/src/NTPClientTest.h
new file mode 100644
index 000000000..7cecfeba5
--- /dev/null
+++ b/Net/testsuite/src/NTPClientTest.h
@@ -0,0 +1,64 @@
+//
+// NTPClientTest.h
+//
+// $Id: //poco/1.4/Net/testsuite/src/NTPClientTest.h#1 $
+//
+// Definition of the NTPClientTest class.
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#ifndef NTPClientTest_INCLUDED
+#define NTPClientTest_INCLUDED
+
+
+#include "Poco/Net/Net.h"
+#include "CppUnit/TestCase.h"
+#include "Poco/Net/NTPClient.h"
+#include "Poco/Net/NTPEventArgs.h"
+
+
+class NTPClientTest: public CppUnit::TestCase
+{
+public:
+ NTPClientTest(const std::string& name);
+ ~NTPClientTest();
+
+ void testTimeSync();
+
+ void setUp();
+ void tearDown();
+
+ static CppUnit::Test* suite();
+
+ void onResponse(const void* pSender, Poco::Net::NTPEventArgs& args);
+private:
+ Poco::Net::NTPClient _ntpClient;
+};
+
+
+#endif // NTPClientTest_INCLUDED
diff --git a/Net/testsuite/src/NTPClientTestSuite.cpp b/Net/testsuite/src/NTPClientTestSuite.cpp
new file mode 100644
index 000000000..4928fc164
--- /dev/null
+++ b/Net/testsuite/src/NTPClientTestSuite.cpp
@@ -0,0 +1,44 @@
+//
+// NTPClientTestSuite.cpp
+//
+// $Id: //poco/1.4/Net/testsuite/src/NTPClientTestSuite.cpp#1 $
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#include "NTPClientTestSuite.h"
+#include "NTPClientTest.h"
+
+
+CppUnit::Test* NTPClientTestSuite::suite()
+{
+ CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NTPClientTestSuite");
+
+ pSuite->addTest(NTPClientTest::suite());
+
+ return pSuite;
+}
diff --git a/Net/testsuite/src/NTPClientTestSuite.h b/Net/testsuite/src/NTPClientTestSuite.h
new file mode 100644
index 000000000..1090d5275
--- /dev/null
+++ b/Net/testsuite/src/NTPClientTestSuite.h
@@ -0,0 +1,49 @@
+//
+// NTPClientTestSuite.h
+//
+// $Id: //poco/1.4/Net/testsuite/src/NTPClientTestSuite.h#1 $
+//
+// Definition of the NTPClientTestSuite class.
+//
+// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+
+
+#ifndef NTPClientTestSuite_INCLUDED
+#define NTPClientTestSuite_INCLUDED
+
+
+#include "CppUnit/TestSuite.h"
+
+
+class NTPClientTestSuite
+{
+public:
+ static CppUnit::Test* suite();
+};
+
+
+#endif // NTPClientTestSuite_INCLUDED
diff --git a/Net/testsuite/src/NetTestSuite.cpp b/Net/testsuite/src/NetTestSuite.cpp
index 6a152487d..3220e8c2f 100644
--- a/Net/testsuite/src/NetTestSuite.cpp
+++ b/Net/testsuite/src/NetTestSuite.cpp
@@ -43,6 +43,7 @@
#include "FTPClientTestSuite.h"
#include "MailTestSuite.h"
#include "ICMPClientTestSuite.h"
+#include "NTPClientTestSuite.h"
#include "WebSocketTestSuite.h"
#include "SyslogTest.h"
@@ -63,6 +64,7 @@ CppUnit::Test* NetTestSuite::suite()
pSuite->addTest(FTPClientTestSuite::suite());
pSuite->addTest(MailTestSuite::suite());
pSuite->addTest(ICMPClientTestSuite::suite());
+ pSuite->addTest(NTPClientTestSuite::suite());
pSuite->addTest(WebSocketTestSuite::suite());
pSuite->addTest(SyslogTest::suite());