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());