// $Id: NTP.cc 6219 2008-10-01 05:39:07Z vern $ // // See the file "COPYING" in the main distribution directory for copyright. #include "config.h" #include "NetVar.h" #include "NTP.h" #include "Sessions.h" #include "Event.h" NTP_Analyzer::NTP_Analyzer(Connection* conn) : Analyzer(AnalyzerTag::NTP, conn) { ADD_ANALYZER_TIMER(&NTP_Analyzer::ExpireTimer, network_time + ntp_session_timeout, 1, TIMER_NTP_EXPIRE); } void NTP_Analyzer::Done() { Analyzer::Done(); Event(udp_session_done); } void NTP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); // Actually we could just get rid of the Request/Reply and simply use // the code of Message(). But for now we use it as an example of how // to convert an old-style UDP analyzer. if ( is_orig ) Request(data, len); else Reply(data, len); } int NTP_Analyzer::Request(const u_char* data, int len) { Message(data, len); return 1; } int NTP_Analyzer::Reply(const u_char* data, int len) { Message(data, len); return 1; } void NTP_Analyzer::Message(const u_char* data, int len) { if ( (unsigned) len < sizeof(struct ntpdata) ) { Weird("truncated_NTP"); return; } struct ntpdata* ntp_data = (struct ntpdata *) data; len -= sizeof *ntp_data; data += sizeof *ntp_data; RecordVal* msg = new RecordVal(ntp_msg); unsigned int code = ntp_data->status & 0x7; msg->Assign(0, new Val((unsigned int) (ntohl(ntp_data->refid)), TYPE_COUNT)); msg->Assign(1, new Val(code, TYPE_COUNT)); msg->Assign(2, new Val((unsigned int) ntp_data->stratum, TYPE_COUNT)); msg->Assign(3, new Val((unsigned int) ntp_data->ppoll, TYPE_COUNT)); msg->Assign(4, new Val((unsigned int) ntp_data->precision, TYPE_INT)); msg->Assign(5, new Val(ShortFloat(ntp_data->distance), TYPE_INTERVAL)); msg->Assign(6, new Val(ShortFloat(ntp_data->dispersion), TYPE_INTERVAL)); msg->Assign(7, new Val(LongFloat(ntp_data->reftime), TYPE_TIME)); msg->Assign(8, new Val(LongFloat(ntp_data->org), TYPE_TIME)); msg->Assign(9, new Val(LongFloat(ntp_data->rec), TYPE_TIME)); msg->Assign(10, new Val(LongFloat(ntp_data->xmt), TYPE_TIME)); val_list* vl = new val_list; vl->append(BuildConnVal()); vl->append(msg); vl->append(new StringVal(new BroString(data, len, 0))); ConnectionEvent(ntp_message, vl); } double NTP_Analyzer::ShortFloat(struct s_fixedpt fp) { return ConvertToDouble(ntohs(fp.int_part), ntohs(fp.fraction), 65536.0); } double NTP_Analyzer::LongFloat(struct l_fixedpt fp) { double t = ConvertToDouble(ntohl(fp.int_part), ntohl(fp.fraction), 4294967296.0); return t ? t - JAN_1970 : 0.0; } double NTP_Analyzer::ConvertToDouble(unsigned int int_part, unsigned int fraction, double frac_base) { return double(int_part) + double(fraction) / frac_base; } void NTP_Analyzer::ExpireTimer(double /* t */) { Event(connection_timeout); sessions->Remove(Conn()); }