/* * Copyright (c) 2015 Carsten Larsen * Copyright (c) 2014 Poul-Henning Kamp * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include "ntimed_platform.h" #include "ntimed.h" #include "ntp.h" #include "udp.h" #define ARGSFORMAT "D=DURATION/N,M=MONITOR/K,T=TRACEFILE/K,SERVERS/M/A,SHOW/S,QUIET/S" const char *vers = "\0$VER: ntimed-poll" AMIGA_VERSION; struct RDArgs *rdargs = NULL; struct udp_socket *usc = NULL; struct ntp_peerset *npl = NULL; struct todolist *tdl = NULL; struct ntimedargs { long *duration; char *monitor; char *tracefile; char **servers; long show; long quiet; }; static void init_logic(struct ntimedargs *args); static void clean_exit(); int main(int argc, char **argv) { int result = 0; struct ntimedargs args = { NULL, NULL, NULL, NULL, FALSE, FALSE }; atexit(clean_exit); if((result = amiga_open_libs()) != 0) { exit(result); } rdargs = ReadArgs((STRPTR)ARGSFORMAT, (APTR)&args, NULL); if (!rdargs) { PrintFault(IoErr(), (STRPTR)argv[0]); exit(5); } if (!args.quiet) { EnableDebug(); if (args.show) { EnableTraceDebug(); } } if (args.tracefile) { ArgTracefile(args.tracefile); } init_logic(&args); NTP_PeerSet_Poll(NULL, npl, usc, tdl); (void)TODO_Run(NULL, tdl); return result; } static void mps_filter(struct ocx *ocx, const struct ntp_peer *np) { char buf[256]; NTP_Tool_Format(buf, sizeof buf, np->rx_pkt); Put(ocx, OCX_TRACE, "Poll %s %s %s\n", np->hostname, np->ip, buf); } static enum todo_e __match_proto__(todo_f) mps_mon(struct ocx *ocx, struct todolist *tdl, void *priv) { char buf[256]; struct ntp_peer *np; int i; (void)ocx; (void)tdl; CAST_OBJ_NOTNULL(np, priv, NTP_PEER_MAGIC); i = NTP_Peer_Poll(ocx, usc, np, 0.2); if (i == 1) { NTP_Tool_Format(buf, sizeof buf, np->rx_pkt); Put(ocx, OCX_TRACE, "Monitor %s %s %s\n", np->hostname, np->ip, buf); } else { Put(ocx, OCX_TRACE, "Monitor_err %s %s %d\n", np->hostname, np->ip, i); } return(TODO_OK); } static enum todo_e __match_proto__(todo_f) mps_end(struct ocx *ocx, struct todolist *tdl, void *priv) { (void)tdl; (void)priv; Put(ocx, OCX_TRACE, "# Run completed\n"); return(TODO_FAIL); } static void init_logic(struct ntimedargs *args) { struct ntp_peer *mon; struct ntp_peer *np; int npeer; int i; long duration; mon = NULL; npeer = 0; duration = 1800; if (args->duration) { duration = *(args->duration); if(duration < 1) { Put(NULL, OCX_DEBUG, "Invalid DURATION value.\n"); exit(1); } } if(args->monitor) { mon = NTP_Peer_NewLookup(NULL, args->monitor); if (mon == NULL) { Put(NULL, OCX_DEBUG, "MONITOR did not resolve.\n"); exit(1); } } tdl = TODO_NewList(); Time_Amiga_Passive(); npl = NTP_PeerSet_New(NULL); AN(npl); for (i = 0; args->servers[i]; i++) npeer += NTP_PeerSet_Add(NULL, npl, args->servers[i]); Put(NULL, OCX_TRACE, "# NTIMED Format poll-server 1.0\n"); Put(NULL, OCX_TRACE, "# Found %d peers\n", npeer); if (npeer == 0) { Put(NULL, OCX_DEBUG, "No NTP peers found\n"); exit(1); } NTP_PeerSet_Foreach(np, npl) { Put(NULL, OCX_TRACE, "# Peer %s %s\n", np->hostname, np->ip); np->filter_func = mps_filter; } if (mon != NULL) Put(NULL, OCX_TRACE, "# Monitor %s %s\n", mon->hostname, mon->ip); usc = UdpTimedSocket(NULL); if (usc == NULL) { Put(NULL, OCX_DEBUG, "Could not open UDP socket\n"); exit(1); } Put(NULL, OCX_TRACE, "# Duration of run set to %d seconds\n", duration); TODO_ScheduleRel(tdl, mps_end, NULL, duration, 0, "End task"); if (mon != NULL) TODO_ScheduleRel(tdl, mps_mon, mon, 0, 32, "Monitor"); amiga_init_offset(); } static void clean_exit() { ArgTracefile(NULL); if(usc) { UDP_Socket_Destroy(usc); usc = NULL; } if (rdargs) { FreeArgs(rdargs); rdargs = NULL; } amiga_close_libs(); freeall(); }