📄 ntp_request.c
字号:
/* * This is a bit unstructured, but I like to be careful. * We check to see that every peer exists and is actually * configured. If so, we remove them. If not, we return * an error. */ items = INFO_NITEMS(inpkt->err_nitems); cp = (struct conf_unpeer *)inpkt->data; bad = 0; while (items-- > 0 && !bad) { memset(&temp_cp, 0, sizeof(temp_cp)); memset(&peeraddr, 0, sizeof(peeraddr)); memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); if (client_v6_capable && temp_cp.v6_flag != 0) { peeraddr.ss_family = AF_INET6; GET_INADDR6(peeraddr) = temp_cp.peeraddr6; } else { peeraddr.ss_family = AF_INET; GET_INADDR(peeraddr) = temp_cp.peeraddr; } NSRCPORT(&peeraddr) = htons(NTP_PORT);#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR peeraddr.ss_len = SOCKLEN(&peeraddr);#endif found = 0; peer = (struct peer *)0;#ifdef DEBUG if (debug) printf("searching for %s\n", stoa(&peeraddr));#endif while (!found) { peer = findexistingpeer(&peeraddr, peer, -1); if (peer == (struct peer *)0) break; if (peer->flags & FLAG_CONFIG) found = 1; } if (!found) bad = 1; cp = (struct conf_unpeer *) ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); } if (bad) { req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); return; } /* * Now do it in earnest. */ items = INFO_NITEMS(inpkt->err_nitems); cp = (struct conf_unpeer *)inpkt->data; while (items-- > 0) { memset(&temp_cp, 0, sizeof(temp_cp)); memset(&peeraddr, 0, sizeof(peeraddr)); memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); if (client_v6_capable && temp_cp.v6_flag != 0) { peeraddr.ss_family = AF_INET6; GET_INADDR6(peeraddr) = temp_cp.peeraddr6; } else { peeraddr.ss_family = AF_INET; GET_INADDR(peeraddr) = temp_cp.peeraddr; } NSRCPORT(&peeraddr) = htons(NTP_PORT);#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR peeraddr.ss_len = SOCKLEN(&peeraddr);#endif peer_unconfig(&peeraddr, (struct interface *)0, -1); cp = (struct conf_unpeer *) ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); } req_ack(srcadr, inter, inpkt, INFO_OKAY);}/* * set_sys_flag - set system flags */static voidset_sys_flag( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ setclr_flags(srcadr, inter, inpkt, 1);}/* * clr_sys_flag - clear system flags */static voidclr_sys_flag( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ setclr_flags(srcadr, inter, inpkt, 0);}/* * setclr_flags - do the grunge work of flag setting/clearing */static voidsetclr_flags( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt, u_long set ){ register u_int flags; if (INFO_NITEMS(inpkt->err_nitems) > 1) { msyslog(LOG_ERR, "setclr_flags: err_nitems > 1"); req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); return; } flags = ((struct conf_sys_flags *)inpkt->data)->flags; if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) { msyslog(LOG_ERR, "setclr_flags: extra flags: %#x", flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)); req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); return; } if (flags & SYS_FLAG_BCLIENT) proto_config(PROTO_BROADCLIENT, set, 0., NULL); if (flags & SYS_FLAG_PPS) proto_config(PROTO_PPS, set, 0., NULL); if (flags & SYS_FLAG_NTP) proto_config(PROTO_NTP, set, 0., NULL); if (flags & SYS_FLAG_KERNEL) proto_config(PROTO_KERNEL, set, 0., NULL); if (flags & SYS_FLAG_MONITOR) proto_config(PROTO_MONITOR, set, 0., NULL); if (flags & SYS_FLAG_FILEGEN) proto_config(PROTO_FILEGEN, set, 0., NULL); if (flags & SYS_FLAG_AUTH) proto_config(PROTO_AUTHENTICATE, set, 0., NULL); if (flags & SYS_FLAG_CAL) proto_config(PROTO_CAL, set, 0., NULL); req_ack(srcadr, inter, inpkt, INFO_OKAY);}/* * list_restrict - return the restrict list */static voidlist_restrict( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ register struct info_restrict *ir; register struct restrictlist *rl; register struct restrictlist6 *rl6;#ifdef DEBUG if (debug > 2) printf("wants restrict list summary\n");#endif ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_restrict)); for (rl = restrictlist; rl != 0 && ir != 0; rl = rl->next) { ir->addr = htonl(rl->addr); if (client_v6_capable) ir->v6_flag = 0; ir->mask = htonl(rl->mask); ir->count = htonl((u_int32)rl->count); ir->flags = htons(rl->flags); ir->mflags = htons(rl->mflags); ir = (struct info_restrict *)more_pkt(); } if (client_v6_capable) for (rl6 = restrictlist6; rl6 != 0 && ir != 0; rl6 = rl6->next) { ir->addr6 = rl6->addr6; ir->mask6 = rl6->mask6; ir->v6_flag = 1; ir->count = htonl((u_int32)rl6->count); ir->flags = htons(rl6->flags); ir->mflags = htons(rl6->mflags); ir = (struct info_restrict *)more_pkt(); } flush_pkt();}/* * do_resaddflags - add flags to a restrict entry (or create one) */static voiddo_resaddflags( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS);}/* * do_ressubflags - remove flags from a restrict entry */static voiddo_ressubflags( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG);}/* * do_unrestrict - remove a restrict entry from the list */static voiddo_unrestrict( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE);}/* * do_restrict - do the dirty stuff of dealing with restrictions */static voiddo_restrict( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt, int op ){ register struct conf_restrict *cr; register int items; struct sockaddr_storage matchaddr; struct sockaddr_storage matchmask; int bad; /* * Do a check of the flags to make sure that only * the NTPPORT flag is set, if any. If not, complain * about it. Note we are very picky here. */ items = INFO_NITEMS(inpkt->err_nitems); cr = (struct conf_restrict *)inpkt->data; bad = 0; while (items-- > 0 && !bad) { if (cr->mflags & ~(RESM_NTPONLY)) bad |= 1; if (cr->flags & ~(RES_ALLFLAGS)) bad |= 2; if (cr->mask != htonl(INADDR_ANY)) { if (client_v6_capable && cr->v6_flag != 0) { if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6)) bad |= 4; } else if (cr->addr == htonl(INADDR_ANY)) bad |= 8; } cr = (struct conf_restrict *)((char *)cr + INFO_ITEMSIZE(inpkt->mbz_itemsize)); } if (bad) { msyslog(LOG_ERR, "do_restrict: bad = %#x", bad); req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); return; } /* * Looks okay, try it out */ items = INFO_NITEMS(inpkt->err_nitems); cr = (struct conf_restrict *)inpkt->data; memset((char *)&matchaddr, 0, sizeof(struct sockaddr_storage)); memset((char *)&matchmask, 0, sizeof(struct sockaddr_storage)); while (items-- > 0) { if (client_v6_capable && cr->v6_flag != 0) { GET_INADDR6(matchaddr) = cr->addr6; GET_INADDR6(matchmask) = cr->mask6; matchaddr.ss_family = AF_INET6; matchmask.ss_family = AF_INET6; } else { GET_INADDR(matchaddr) = cr->addr; GET_INADDR(matchmask) = cr->mask; matchaddr.ss_family = AF_INET; matchmask.ss_family = AF_INET; } hack_restrict(op, &matchaddr, &matchmask, cr->mflags, cr->flags); cr++; } req_ack(srcadr, inter, inpkt, INFO_OKAY);}/* * mon_getlist - return monitor data */static voidmon_getlist_0( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ register struct info_monitor *im; register struct mon_data *md; extern struct mon_data mon_mru_list; extern int mon_enabled;#ifdef DEBUG if (debug > 2) printf("wants monitor 0 list\n");#endif if (!mon_enabled) { req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); return; } im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_monitor)); for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; md = md->mru_next) { im->lasttime = htonl((u_int32)md->avg_interval); im->firsttime = htonl((u_int32)(current_time - md->lasttime)); im->lastdrop = htonl((u_int32)md->drop_count); im->count = htonl((u_int32)(md->count)); if (md->rmtadr.ss_family == AF_INET6) { if (!client_v6_capable) continue; im->addr6 = GET_INADDR6(md->rmtadr); im->v6_flag = 1; } else { im->addr = GET_INADDR(md->rmtadr); if (client_v6_capable) im->v6_flag = 0; } im->port = md->rmtport; im->mode = md->mode; im->version = md->version; im = (struct info_monitor *)more_pkt(); } flush_pkt();}/* * mon_getlist - return monitor data */static voidmon_getlist_1( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ register struct info_monitor_1 *im; register struct mon_data *md; extern struct mon_data mon_mru_list; extern int mon_enabled; if (!mon_enabled) { req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); return; } im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_monitor_1)); for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; md = md->mru_next) { im->lasttime = htonl((u_int32)md->avg_interval); im->firsttime = htonl((u_int32)(current_time - md->lasttime)); im->lastdrop = htonl((u_int32)md->drop_count); im->count = htonl((u_int32)md->count); if (md->rmtadr.ss_family == AF_INET6) { if (!client_v6_capable) continue; im->addr6 = GET_INADDR6(md->rmtadr); im->v6_flag = 1; im->daddr6 = GET_INADDR6(md->interface->sin); } else { im->addr = GET_INADDR(md->rmtadr); if (client_v6_capable) im->v6_flag = 0; im->daddr = (md->cast_flags == MDF_BCAST) ? GET_INADDR(md->interface->bcast) : (md->cast_flags ? (GET_INADDR(md->interface->sin) ? GET_INADDR(md->interface->sin) : GET_INADDR(md->interface->bcast)) : 4); } im->flags = md->cast_flags; im->port = md->rmtport; im->mode = md->mode; im->version = md->version; im = (struct info_monitor_1 *)more_pkt(); } flush_pkt();}/* * Module entry points and the flags they correspond with */struct reset_entry { int flag; /* flag this corresponds to */ void (*handler) P((void)); /* routine to handle request */};struct reset_entry reset_entries[] = { { RESET_FLAG_ALLPEERS, peer_all_reset }, { RESET_FLAG_IO, io_clr_stats }, { RESET_FLAG_SYS, proto_clr_stats }, { RESET_FLAG_MEM, peer_clr_stats }, { RESET_FLAG_TIMER, timer_clr_stats }, { RESET_FLAG_AUTH, reset_auth_stats }, { RESET_FLAG_CTL, ctl_clr_stats }, { 0, 0 }};/* * reset_stats - reset statistic counters here and there */static voidreset_stats( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ u_long flags; struct reset_entry *rent; if (INFO_NITEMS(inpkt->err_nitems) > 1) { msyslog(LOG_ERR, "reset_stats: err_nitems > 1"); req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); return; } flags = ((struct reset_flags *)inpkt->data)->flags; if (flags & ~RESET_ALLFLAGS) { msyslog(LOG_ERR, "reset_stats: reset leaves %#lx", flags & ~RESET_ALLFLAGS); req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); return; } for (rent = reset_entries; rent->flag != 0; rent++) { if (flags & rent->flag) (rent->handler)(); } req_ack(srcadr, inter, inpkt, INFO_OKAY);}/* * reset_peer - clear a peer's statistics */static voidreset_peer( struct sockaddr_storage *srcadr, struct interface *inter, struct req_pkt *inpkt ){ register struct conf_unpeer *cp; register int items;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -