| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ntp_request.c,v 1.7 2012/02/01 22:48:15 kardel Exp $ */ | | 1 | /* $NetBSD: ntp_request.c,v 1.7.16.1 2014/01/06 19:12:22 bouyer Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * ntp_request.c - respond to information requests | | 4 | * ntp_request.c - respond to information requests |
5 | */ | | 5 | */ |
6 | | | 6 | |
7 | #ifdef HAVE_CONFIG_H | | 7 | #ifdef HAVE_CONFIG_H |
8 | # include <config.h> | | 8 | # include <config.h> |
9 | #endif | | 9 | #endif |
10 | | | 10 | |
11 | #include "ntpd.h" | | 11 | #include "ntpd.h" |
12 | #include "ntp_io.h" | | 12 | #include "ntp_io.h" |
13 | #include "ntp_request.h" | | 13 | #include "ntp_request.h" |
14 | #include "ntp_control.h" | | 14 | #include "ntp_control.h" |
| @@ -78,28 +78,27 @@ static void mem_stats (sockaddr_u *, str | | | @@ -78,28 +78,27 @@ static void mem_stats (sockaddr_u *, str |
78 | static void io_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 78 | static void io_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
79 | static void timer_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 79 | static void timer_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
80 | static void loop_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 80 | static void loop_info (sockaddr_u *, struct interface *, struct req_pkt *); |
81 | static void do_conf (sockaddr_u *, struct interface *, struct req_pkt *); | | 81 | static void do_conf (sockaddr_u *, struct interface *, struct req_pkt *); |
82 | static void do_unconf (sockaddr_u *, struct interface *, struct req_pkt *); | | 82 | static void do_unconf (sockaddr_u *, struct interface *, struct req_pkt *); |
83 | static void set_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); | | 83 | static void set_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); |
84 | static void clr_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); | | 84 | static void clr_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); |
85 | static void setclr_flags (sockaddr_u *, struct interface *, struct req_pkt *, u_long); | | 85 | static void setclr_flags (sockaddr_u *, struct interface *, struct req_pkt *, u_long); |
86 | static void list_restrict (sockaddr_u *, struct interface *, struct req_pkt *); | | 86 | static void list_restrict (sockaddr_u *, struct interface *, struct req_pkt *); |
87 | static void do_resaddflags (sockaddr_u *, struct interface *, struct req_pkt *); | | 87 | static void do_resaddflags (sockaddr_u *, struct interface *, struct req_pkt *); |
88 | static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *); | | 88 | static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *); |
89 | static void do_unrestrict (sockaddr_u *, struct interface *, struct req_pkt *); | | 89 | static void do_unrestrict (sockaddr_u *, struct interface *, struct req_pkt *); |
90 | static void do_restrict (sockaddr_u *, struct interface *, struct req_pkt *, int); | | 90 | static void do_restrict (sockaddr_u *, struct interface *, struct req_pkt *, int); |
91 | static void mon_getlist_0 (sockaddr_u *, struct interface *, struct req_pkt *); | | 91 | static void mon_getlist (sockaddr_u *, struct interface *, struct req_pkt *); |
92 | static void mon_getlist_1 (sockaddr_u *, struct interface *, struct req_pkt *); | | | |
93 | static void reset_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 92 | static void reset_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
94 | static void reset_peer (sockaddr_u *, struct interface *, struct req_pkt *); | | 93 | static void reset_peer (sockaddr_u *, struct interface *, struct req_pkt *); |
95 | static void do_key_reread (sockaddr_u *, struct interface *, struct req_pkt *); | | 94 | static void do_key_reread (sockaddr_u *, struct interface *, struct req_pkt *); |
96 | static void trust_key (sockaddr_u *, struct interface *, struct req_pkt *); | | 95 | static void trust_key (sockaddr_u *, struct interface *, struct req_pkt *); |
97 | static void untrust_key (sockaddr_u *, struct interface *, struct req_pkt *); | | 96 | static void untrust_key (sockaddr_u *, struct interface *, struct req_pkt *); |
98 | static void do_trustkey (sockaddr_u *, struct interface *, struct req_pkt *, u_long); | | 97 | static void do_trustkey (sockaddr_u *, struct interface *, struct req_pkt *, u_long); |
99 | static void get_auth_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 98 | static void get_auth_info (sockaddr_u *, struct interface *, struct req_pkt *); |
100 | static void reset_auth_stats (void); | | 99 | static void reset_auth_stats (void); |
101 | static void req_get_traps (sockaddr_u *, struct interface *, struct req_pkt *); | | 100 | static void req_get_traps (sockaddr_u *, struct interface *, struct req_pkt *); |
102 | static void req_set_trap (sockaddr_u *, struct interface *, struct req_pkt *); | | 101 | static void req_set_trap (sockaddr_u *, struct interface *, struct req_pkt *); |
103 | static void req_clr_trap (sockaddr_u *, struct interface *, struct req_pkt *); | | 102 | static void req_clr_trap (sockaddr_u *, struct interface *, struct req_pkt *); |
104 | static void do_setclr_trap (sockaddr_u *, struct interface *, struct req_pkt *, int); | | 103 | static void do_setclr_trap (sockaddr_u *, struct interface *, struct req_pkt *, int); |
105 | static void set_request_keyid (sockaddr_u *, struct interface *, struct req_pkt *); | | 104 | static void set_request_keyid (sockaddr_u *, struct interface *, struct req_pkt *); |
| @@ -139,28 +138,28 @@ static struct req_proc ntp_codes[] = { | | | @@ -139,28 +138,28 @@ static struct req_proc ntp_codes[] = { |
139 | { REQ_UNCONFIG, AUTH, v4sizeof(struct conf_unpeer), | | 138 | { REQ_UNCONFIG, AUTH, v4sizeof(struct conf_unpeer), |
140 | sizeof(struct conf_unpeer), do_unconf }, | | 139 | sizeof(struct conf_unpeer), do_unconf }, |
141 | { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), | | 140 | { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), |
142 | sizeof(struct conf_sys_flags), set_sys_flag }, | | 141 | sizeof(struct conf_sys_flags), set_sys_flag }, |
143 | { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), | | 142 | { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), |
144 | sizeof(struct conf_sys_flags), clr_sys_flag }, | | 143 | sizeof(struct conf_sys_flags), clr_sys_flag }, |
145 | { REQ_GET_RESTRICT, NOAUTH, 0, 0, list_restrict }, | | 144 | { REQ_GET_RESTRICT, NOAUTH, 0, 0, list_restrict }, |
146 | { REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict), | | 145 | { REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict), |
147 | sizeof(struct conf_restrict), do_resaddflags }, | | 146 | sizeof(struct conf_restrict), do_resaddflags }, |
148 | { REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict), | | 147 | { REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict), |
149 | sizeof(struct conf_restrict), do_ressubflags }, | | 148 | sizeof(struct conf_restrict), do_ressubflags }, |
150 | { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict), | | 149 | { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict), |
151 | sizeof(struct conf_restrict), do_unrestrict }, | | 150 | sizeof(struct conf_restrict), do_unrestrict }, |
152 | { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist_0 }, | | 151 | { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist }, |
153 | { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist_1 }, | | 152 | { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist }, |
154 | { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats }, | | 153 | { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats }, |
155 | { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer), | | 154 | { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer), |
156 | sizeof(struct conf_unpeer), reset_peer }, | | 155 | sizeof(struct conf_unpeer), reset_peer }, |
157 | { REQ_REREAD_KEYS, AUTH, 0, 0, do_key_reread }, | | 156 | { REQ_REREAD_KEYS, AUTH, 0, 0, do_key_reread }, |
158 | { REQ_TRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), trust_key }, | | 157 | { REQ_TRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), trust_key }, |
159 | { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key }, | | 158 | { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key }, |
160 | { REQ_AUTHINFO, NOAUTH, 0, 0, get_auth_info }, | | 159 | { REQ_AUTHINFO, NOAUTH, 0, 0, get_auth_info }, |
161 | { REQ_TRAPS, NOAUTH, 0, 0, req_get_traps }, | | 160 | { REQ_TRAPS, NOAUTH, 0, 0, req_get_traps }, |
162 | { REQ_ADD_TRAP, AUTH, v4sizeof(struct conf_trap), | | 161 | { REQ_ADD_TRAP, AUTH, v4sizeof(struct conf_trap), |
163 | sizeof(struct conf_trap), req_set_trap }, | | 162 | sizeof(struct conf_trap), req_set_trap }, |
164 | { REQ_CLR_TRAP, AUTH, v4sizeof(struct conf_trap), | | 163 | { REQ_CLR_TRAP, AUTH, v4sizeof(struct conf_trap), |
165 | sizeof(struct conf_trap), req_clr_trap }, | | 164 | sizeof(struct conf_trap), req_clr_trap }, |
166 | { REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long), | | 165 | { REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long), |
| @@ -604,26 +603,29 @@ process_private( | | | @@ -604,26 +603,29 @@ process_private( |
604 | "process_private: bad pkt length %zu", | | 603 | "process_private: bad pkt length %zu", |
605 | recv_len); | | 604 | recv_len); |
606 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 605 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
607 | return; | | 606 | return; |
608 | } | | 607 | } |
609 | if (!mod_okay || !authhavekey(info_auth_keyid)) { | | 608 | if (!mod_okay || !authhavekey(info_auth_keyid)) { |
610 | DPRINTF(5, ("failed auth mod_okay %d\n", | | 609 | DPRINTF(5, ("failed auth mod_okay %d\n", |
611 | mod_okay)); | | 610 | mod_okay)); |
612 | #ifdef DEBUG | | 611 | #ifdef DEBUG |
613 | msyslog(LOG_DEBUG, | | 612 | msyslog(LOG_DEBUG, |
614 | "process_private: failed auth mod_okay %d\n", | | 613 | "process_private: failed auth mod_okay %d\n", |
615 | mod_okay); | | 614 | mod_okay); |
616 | #endif | | 615 | #endif |
| | | 616 | if (!mod_okay) { |
| | | 617 | sys_restricted++; |
| | | 618 | } |
617 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); | | 619 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); |
618 | return; | | 620 | return; |
619 | } | | 621 | } |
620 | | | 622 | |
621 | /* | | 623 | /* |
622 | * calculate absolute time difference between xmit time stamp | | 624 | * calculate absolute time difference between xmit time stamp |
623 | * and receive time stamp. If too large, too bad. | | 625 | * and receive time stamp. If too large, too bad. |
624 | */ | | 626 | */ |
625 | NTOHL_FP(&tailinpkt->tstamp, &ftmp); | | 627 | NTOHL_FP(&tailinpkt->tstamp, &ftmp); |
626 | L_SUB(&ftmp, &rbufp->recv_time); | | 628 | L_SUB(&ftmp, &rbufp->recv_time); |
627 | LFPTOD(&ftmp, dtemp); | | 629 | LFPTOD(&ftmp, dtemp); |
628 | if (fabs(dtemp) > INFO_TS_MAXSKEW) { | | 630 | if (fabs(dtemp) > INFO_TS_MAXSKEW) { |
629 | /* | | 631 | /* |
| @@ -815,54 +817,62 @@ peer_list_sum( | | | @@ -815,54 +817,62 @@ peer_list_sum( |
815 | } | | 817 | } |
816 | | | 818 | |
817 | | | 819 | |
818 | /* | | 820 | /* |
819 | * peer_info - send information for one or more peers | | 821 | * peer_info - send information for one or more peers |
820 | */ | | 822 | */ |
821 | static void | | 823 | static void |
822 | peer_info ( | | 824 | peer_info ( |
823 | sockaddr_u *srcadr, | | 825 | sockaddr_u *srcadr, |
824 | struct interface *inter, | | 826 | struct interface *inter, |
825 | struct req_pkt *inpkt | | 827 | struct req_pkt *inpkt |
826 | ) | | 828 | ) |
827 | { | | 829 | { |
828 | register struct info_peer_list *ipl; | | 830 | struct info_peer_list ipl; |
829 | register struct peer *pp; | | 831 | register struct peer *pp; |
830 | register struct info_peer *ip; | | 832 | register struct info_peer *ip; |
831 | register int items; | | 833 | register int items; |
| | | 834 | size_t item_sz; |
| | | 835 | char * datap; |
832 | register int i, j; | | 836 | register int i, j; |
833 | sockaddr_u addr; | | 837 | sockaddr_u addr; |
834 | extern struct peer *sys_peer; | | 838 | extern struct peer *sys_peer; |
835 | l_fp ltmp; | | 839 | l_fp ltmp; |
836 | | | 840 | |
837 | items = INFO_NITEMS(inpkt->err_nitems); | | 841 | items = INFO_NITEMS(inpkt->err_nitems); |
838 | ipl = (struct info_peer_list *) inpkt->data; | | 842 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
839 | | | 843 | datap = inpkt->data; |
| | | 844 | if (item_sz != sizeof(ipl)) { |
| | | 845 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 846 | return; |
| | | 847 | } |
840 | ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt, | | 848 | ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt, |
841 | v6sizeof(struct info_peer)); | | 849 | v6sizeof(struct info_peer)); |
842 | while (items-- > 0 && ip != 0) { | | 850 | while (items-- > 0 && ip != 0) { |
| | | 851 | memset(&ipl,0,sizeof(ipl)); |
| | | 852 | memcpy(&ipl, datap, item_sz); |
843 | ZERO_SOCK(&addr); | | 853 | ZERO_SOCK(&addr); |
844 | NSRCPORT(&addr) = ipl->port; | | 854 | NSRCPORT(&addr) = ipl.port; |
845 | if (client_v6_capable && ipl->v6_flag) { | | 855 | if (client_v6_capable && ipl.v6_flag) { |
846 | AF(&addr) = AF_INET6; | | 856 | AF(&addr) = AF_INET6; |
847 | SOCK_ADDR6(&addr) = ipl->addr6; | | 857 | SOCK_ADDR6(&addr) = ipl.addr6; |
848 | } else { | | 858 | } else { |
849 | AF(&addr) = AF_INET; | | 859 | AF(&addr) = AF_INET; |
850 | NSRCADR(&addr) = ipl->addr; | | 860 | NSRCADR(&addr) = ipl.addr; |
851 | } | | 861 | } |
852 | #ifdef ISC_PLATFORM_HAVESALEN | | 862 | #ifdef ISC_PLATFORM_HAVESALEN |
853 | addr.sa.sa_len = SOCKLEN(&addr); | | 863 | addr.sa.sa_len = SOCKLEN(&addr); |
854 | #endif | | 864 | #endif |
855 | ipl++; | | 865 | datap += item_sz; |
856 | pp = findexistingpeer(&addr, NULL, -1, 0); | | 866 | pp = findexistingpeer(&addr, NULL, -1, 0); |
857 | if (NULL == pp) | | 867 | if (NULL == pp) |
858 | continue; | | 868 | continue; |
859 | if (IS_IPV6(srcadr)) { | | 869 | if (IS_IPV6(srcadr)) { |
860 | if (pp->dstadr) | | 870 | if (pp->dstadr) |
861 | ip->dstadr6 = | | 871 | ip->dstadr6 = |
862 | (MDF_BCAST == pp->cast_flags) | | 872 | (MDF_BCAST == pp->cast_flags) |
863 | ? SOCK_ADDR6(&pp->dstadr->bcast) | | 873 | ? SOCK_ADDR6(&pp->dstadr->bcast) |
864 | : SOCK_ADDR6(&pp->dstadr->sin); | | 874 | : SOCK_ADDR6(&pp->dstadr->sin); |
865 | else | | 875 | else |
866 | memset(&ip->dstadr6, 0, sizeof(ip->dstadr6)); | | 876 | memset(&ip->dstadr6, 0, sizeof(ip->dstadr6)); |
867 | | | 877 | |
868 | ip->srcadr6 = SOCK_ADDR6(&pp->srcadr); | | 878 | ip->srcadr6 = SOCK_ADDR6(&pp->srcadr); |
| @@ -948,59 +958,67 @@ peer_info ( | | | @@ -948,59 +958,67 @@ peer_info ( |
948 | } | | 958 | } |
949 | | | 959 | |
950 | | | 960 | |
951 | /* | | 961 | /* |
952 | * peer_stats - send statistics for one or more peers | | 962 | * peer_stats - send statistics for one or more peers |
953 | */ | | 963 | */ |
954 | static void | | 964 | static void |
955 | peer_stats ( | | 965 | peer_stats ( |
956 | sockaddr_u *srcadr, | | 966 | sockaddr_u *srcadr, |
957 | struct interface *inter, | | 967 | struct interface *inter, |
958 | struct req_pkt *inpkt | | 968 | struct req_pkt *inpkt |
959 | ) | | 969 | ) |
960 | { | | 970 | { |
961 | register struct info_peer_list *ipl; | | 971 | struct info_peer_list ipl; |
962 | register struct peer *pp; | | 972 | register struct peer *pp; |
963 | register struct info_peer_stats *ip; | | 973 | register struct info_peer_stats *ip; |
964 | register int items; | | 974 | register int items; |
| | | 975 | size_t item_sz; |
| | | 976 | char * datap; |
965 | sockaddr_u addr; | | 977 | sockaddr_u addr; |
966 | extern struct peer *sys_peer; | | 978 | extern struct peer *sys_peer; |
967 | | | 979 | |
968 | #ifdef DEBUG | | 980 | #ifdef DEBUG |
969 | if (debug) | | 981 | if (debug) |
970 | printf("peer_stats: called\n"); | | 982 | printf("peer_stats: called\n"); |
971 | #endif | | 983 | #endif |
972 | items = INFO_NITEMS(inpkt->err_nitems); | | 984 | items = INFO_NITEMS(inpkt->err_nitems); |
973 | ipl = (struct info_peer_list *) inpkt->data; | | 985 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
| | | 986 | datap = inpkt->data; |
| | | 987 | if (item_sz > sizeof(ipl)) { |
| | | 988 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 989 | return; |
| | | 990 | } |
974 | ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt, | | 991 | ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt, |
975 | v6sizeof(struct info_peer_stats)); | | 992 | v6sizeof(struct info_peer_stats)); |
976 | while (items-- > 0 && ip != 0) { | | 993 | while (items-- > 0 && ip != 0) { |
| | | 994 | memset(&ipl,0,sizeof(ipl)); |
| | | 995 | memcpy(&ipl, datap, item_sz); |
977 | memset((char *)&addr, 0, sizeof(addr)); | | 996 | memset((char *)&addr, 0, sizeof(addr)); |
978 | NSRCPORT(&addr) = ipl->port; | | 997 | NSRCPORT(&addr) = ipl.port; |
979 | if (client_v6_capable && ipl->v6_flag) { | | 998 | if (client_v6_capable && ipl.v6_flag) { |
980 | AF(&addr) = AF_INET6; | | 999 | AF(&addr) = AF_INET6; |
981 | SOCK_ADDR6(&addr) = ipl->addr6; | | 1000 | SOCK_ADDR6(&addr) = ipl.addr6; |
982 | } else { | | 1001 | } else { |
983 | AF(&addr) = AF_INET; | | 1002 | AF(&addr) = AF_INET; |
984 | NSRCADR(&addr) = ipl->addr; | | 1003 | NSRCADR(&addr) = ipl.addr; |
985 | } | | 1004 | } |
986 | #ifdef ISC_PLATFORM_HAVESALEN | | 1005 | #ifdef ISC_PLATFORM_HAVESALEN |
987 | addr.sa.sa_len = SOCKLEN(&addr); | | 1006 | addr.sa.sa_len = SOCKLEN(&addr); |
988 | #endif | | 1007 | #endif |
989 | DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n", | | 1008 | DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n", |
990 | stoa(&addr), ipl->port, NSRCPORT(&addr))); | | 1009 | stoa(&addr), ipl.port, NSRCPORT(&addr))); |
991 | | | 1010 | |
992 | ipl = (struct info_peer_list *)((char *)ipl + | | 1011 | datap += item_sz; |
993 | INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
994 | | | 1012 | |
995 | pp = findexistingpeer(&addr, NULL, -1, 0); | | 1013 | pp = findexistingpeer(&addr, NULL, -1, 0); |
996 | if (NULL == pp) | | 1014 | if (NULL == pp) |
997 | continue; | | 1015 | continue; |
998 | | | 1016 | |
999 | DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr))); | | 1017 | DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr))); |
1000 | | | 1018 | |
1001 | if (IS_IPV4(&pp->srcadr)) { | | 1019 | if (IS_IPV4(&pp->srcadr)) { |
1002 | if (pp->dstadr) { | | 1020 | if (pp->dstadr) { |
1003 | if (!pp->processed) | | 1021 | if (!pp->processed) |
1004 | ip->dstadr = NSRCADR(&pp->dstadr->sin); | | 1022 | ip->dstadr = NSRCADR(&pp->dstadr->sin); |
1005 | else { | | 1023 | else { |
1006 | if (MDF_BCAST == pp->cast_flags) | | 1024 | if (MDF_BCAST == pp->cast_flags) |
| @@ -1316,75 +1334,49 @@ loop_info( | | | @@ -1316,75 +1334,49 @@ loop_info( |
1316 | } | | 1334 | } |
1317 | | | 1335 | |
1318 | | | 1336 | |
1319 | /* | | 1337 | /* |
1320 | * do_conf - add a peer to the configuration list | | 1338 | * do_conf - add a peer to the configuration list |
1321 | */ | | 1339 | */ |
1322 | static void | | 1340 | static void |
1323 | do_conf( | | 1341 | do_conf( |
1324 | sockaddr_u *srcadr, | | 1342 | sockaddr_u *srcadr, |
1325 | struct interface *inter, | | 1343 | struct interface *inter, |
1326 | struct req_pkt *inpkt | | 1344 | struct req_pkt *inpkt |
1327 | ) | | 1345 | ) |
1328 | { | | 1346 | { |
1329 | static u_long soonest_ifrescan_time = 0; | | | |
1330 | int items; | | 1347 | int items; |
| | | 1348 | size_t item_sz; |
| | | 1349 | char * datap; |
1331 | u_int fl; | | 1350 | u_int fl; |
1332 | struct conf_peer *cp; | | | |
1333 | struct conf_peer temp_cp; | | 1351 | struct conf_peer temp_cp; |
1334 | sockaddr_u peeraddr; | | 1352 | sockaddr_u peeraddr; |
1335 | | | 1353 | |
1336 | /* | | 1354 | /* |
1337 | * Do a check of everything to see that it looks | | 1355 | * Do a check of everything to see that it looks |
1338 | * okay. If not, complain about it. Note we are | | 1356 | * okay. If not, complain about it. Note we are |
1339 | * very picky here. | | 1357 | * very picky here. |
1340 | */ | | 1358 | */ |
1341 | items = INFO_NITEMS(inpkt->err_nitems); | | 1359 | items = INFO_NITEMS(inpkt->err_nitems); |
1342 | cp = (struct conf_peer *)inpkt->data; | | 1360 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
1343 | memset(&temp_cp, 0, sizeof(struct conf_peer)); | | 1361 | datap = inpkt->data; |
1344 | memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | 1362 | if (item_sz > sizeof(temp_cp)) { |
1345 | | | | |
1346 | #if 0 /* paranoid checking - these are done in newpeer() */ | | | |
1347 | fl = 0; | | | |
1348 | while (items-- > 0 && !fl) { | | | |
1349 | if (((temp_cp.version) > NTP_VERSION) | | | |
1350 | || ((temp_cp.version) < NTP_OLDVERSION)) | | | |
1351 | fl = 1; | | | |
1352 | if (temp_cp.hmode != MODE_ACTIVE | | | |
1353 | && temp_cp.hmode != MODE_CLIENT | | | |
1354 | && temp_cp.hmode != MODE_BROADCAST) | | | |
1355 | fl = 1; | | | |
1356 | if (temp_cp.flags & ~(CONF_FLAG_PREFER | CONF_FLAG_BURST | | | | |
1357 | CONF_FLAG_IBURST | CONF_FLAG_SKEY)) | | | |
1358 | fl = 1; | | | |
1359 | cp = (struct conf_peer *) | | | |
1360 | ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1361 | } | | | |
1362 | | | | |
1363 | if (fl) { | | | |
1364 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1363 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
1365 | return; | | 1364 | return; |
1366 | } | | 1365 | } |
1367 | #endif /* end paranoid checking */ | | | |
1368 | | | | |
1369 | /* | | | |
1370 | * Looks okay, try it out | | | |
1371 | */ | | | |
1372 | items = INFO_NITEMS(inpkt->err_nitems); | | | |
1373 | cp = (struct conf_peer *)inpkt->data; | | | |
1374 | | | 1366 | |
1375 | while (items-- > 0) { | | 1367 | while (items-- > 0) { |
1376 | memset(&temp_cp, 0, sizeof(struct conf_peer)); | | 1368 | memset(&temp_cp, 0, sizeof(struct conf_peer)); |
1377 | memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | 1369 | memcpy(&temp_cp, datap, item_sz); |
1378 | ZERO_SOCK(&peeraddr); | | 1370 | ZERO_SOCK(&peeraddr); |
1379 | | | 1371 | |
1380 | fl = 0; | | 1372 | fl = 0; |
1381 | if (temp_cp.flags & CONF_FLAG_PREFER) | | 1373 | if (temp_cp.flags & CONF_FLAG_PREFER) |
1382 | fl |= FLAG_PREFER; | | 1374 | fl |= FLAG_PREFER; |
1383 | if (temp_cp.flags & CONF_FLAG_BURST) | | 1375 | if (temp_cp.flags & CONF_FLAG_BURST) |
1384 | fl |= FLAG_BURST; | | 1376 | fl |= FLAG_BURST; |
1385 | if (temp_cp.flags & CONF_FLAG_IBURST) | | 1377 | if (temp_cp.flags & CONF_FLAG_IBURST) |
1386 | fl |= FLAG_IBURST; | | 1378 | fl |= FLAG_IBURST; |
1387 | #ifdef OPENSSL | | 1379 | #ifdef OPENSSL |
1388 | if (temp_cp.flags & CONF_FLAG_SKEY) | | 1380 | if (temp_cp.flags & CONF_FLAG_SKEY) |
1389 | fl |= FLAG_SKEY; | | 1381 | fl |= FLAG_SKEY; |
1390 | #endif /* OPENSSL */ | | 1382 | #endif /* OPENSSL */ |
| @@ -1408,44 +1400,27 @@ do_conf( | | | @@ -1408,44 +1400,27 @@ do_conf( |
1408 | #ifdef ISC_PLATFORM_HAVESALEN | | 1400 | #ifdef ISC_PLATFORM_HAVESALEN |
1409 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 1401 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
1410 | #endif | | 1402 | #endif |
1411 | | | 1403 | |
1412 | /* XXX W2DO? minpoll/maxpoll arguments ??? */ | | 1404 | /* XXX W2DO? minpoll/maxpoll arguments ??? */ |
1413 | if (peer_config(&peeraddr, (struct interface *)0, | | 1405 | if (peer_config(&peeraddr, (struct interface *)0, |
1414 | temp_cp.hmode, temp_cp.version, temp_cp.minpoll, | | 1406 | temp_cp.hmode, temp_cp.version, temp_cp.minpoll, |
1415 | temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid, | | 1407 | temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid, |
1416 | NULL) == 0) { | | 1408 | NULL) == 0) { |
1417 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 1409 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
1418 | return; | | 1410 | return; |
1419 | } | | 1411 | } |
1420 | | | 1412 | |
1421 | /* | | 1413 | datap += item_sz; |
1422 | * ntp_intres.c uses REQ_CONFIG/doconf() to add each | | | |
1423 | * server after its name is resolved. If we have been | | | |
1424 | * disconnected from the network, it may notice the | | | |
1425 | * network has returned and add the first server while | | | |
1426 | * the relevant interface is still disabled, awaiting | | | |
1427 | * the next interface rescan. To get things moving | | | |
1428 | * more quickly, trigger an interface scan now, except | | | |
1429 | * if we have done so in the last half minute. | | | |
1430 | */ | | | |
1431 | if (soonest_ifrescan_time < current_time) { | | | |
1432 | soonest_ifrescan_time = current_time + 30; | | | |
1433 | timer_interfacetimeout(current_time); | | | |
1434 | DPRINTF(1, ("do_conf triggering interface rescan\n")); | | | |
1435 | } | | | |
1436 | | | | |
1437 | cp = (struct conf_peer *) | | | |
1438 | ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1439 | } | | 1414 | } |
1440 | | | 1415 | |
1441 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1416 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
1442 | } | | 1417 | } |
1443 | | | 1418 | |
1444 | #if 0 | | 1419 | #if 0 |
1445 | /* XXX */ | | 1420 | /* XXX */ |
1446 | /* | | 1421 | /* |
1447 | * dns_a - Snarf DNS info for an association ID | | 1422 | * dns_a - Snarf DNS info for an association ID |
1448 | */ | | 1423 | */ |
1449 | static void | | 1424 | static void |
1450 | dns_a( | | 1425 | dns_a( |
1451 | sockaddr_u *srcadr, | | 1426 | sockaddr_u *srcadr, |
| @@ -1530,92 +1505,97 @@ dns_a( | | | @@ -1530,92 +1505,97 @@ dns_a( |
1530 | } | | 1505 | } |
1531 | #endif /* 0 */ | | 1506 | #endif /* 0 */ |
1532 | | | 1507 | |
1533 | /* | | 1508 | /* |
1534 | * do_unconf - remove a peer from the configuration list | | 1509 | * do_unconf - remove a peer from the configuration list |
1535 | */ | | 1510 | */ |
1536 | static void | | 1511 | static void |
1537 | do_unconf( | | 1512 | do_unconf( |
1538 | sockaddr_u *srcadr, | | 1513 | sockaddr_u *srcadr, |
1539 | struct interface *inter, | | 1514 | struct interface *inter, |
1540 | struct req_pkt *inpkt | | 1515 | struct req_pkt *inpkt |
1541 | ) | | 1516 | ) |
1542 | { | | 1517 | { |
1543 | register struct conf_unpeer *cp; | | | |
1544 | struct conf_unpeer temp_cp; | | 1518 | struct conf_unpeer temp_cp; |
1545 | register int items; | | 1519 | register int items; |
| | | 1520 | size_t item_sz; |
| | | 1521 | char * datap; |
1546 | register struct peer *peer; | | 1522 | register struct peer *peer; |
1547 | sockaddr_u peeraddr; | | 1523 | sockaddr_u peeraddr; |
1548 | int bad, found; | | 1524 | int bad, found; |
1549 | | | 1525 | |
1550 | /* | | 1526 | /* |
1551 | * This is a bit unstructured, but I like to be careful. | | 1527 | * This is a bit unstructured, but I like to be careful. |
1552 | * We check to see that every peer exists and is actually | | 1528 | * We check to see that every peer exists and is actually |
1553 | * configured. If so, we remove them. If not, we return | | 1529 | * configured. If so, we remove them. If not, we return |
1554 | * an error. | | 1530 | * an error. |
1555 | */ | | 1531 | */ |
1556 | items = INFO_NITEMS(inpkt->err_nitems); | | 1532 | items = INFO_NITEMS(inpkt->err_nitems); |
1557 | cp = (struct conf_unpeer *)inpkt->data; | | 1533 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
| | | 1534 | datap = inpkt->data; |
| | | 1535 | if (item_sz > sizeof(temp_cp)) { |
| | | 1536 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 1537 | return; |
| | | 1538 | } |
1558 | | | 1539 | |
1559 | bad = 0; | | 1540 | bad = 0; |
1560 | while (items-- > 0 && !bad) { | | 1541 | while (items-- > 0 && !bad) { |
1561 | memset(&temp_cp, 0, sizeof(temp_cp)); | | 1542 | memset(&temp_cp, 0, sizeof(temp_cp)); |
| | | 1543 | memcpy(&temp_cp, datap, item_sz); |
1562 | ZERO_SOCK(&peeraddr); | | 1544 | ZERO_SOCK(&peeraddr); |
1563 | memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1564 | if (client_v6_capable && temp_cp.v6_flag) { | | 1545 | if (client_v6_capable && temp_cp.v6_flag) { |
1565 | AF(&peeraddr) = AF_INET6; | | 1546 | AF(&peeraddr) = AF_INET6; |
1566 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; | | 1547 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; |
1567 | } else { | | 1548 | } else { |
1568 | AF(&peeraddr) = AF_INET; | | 1549 | AF(&peeraddr) = AF_INET; |
1569 | NSRCADR(&peeraddr) = temp_cp.peeraddr; | | 1550 | NSRCADR(&peeraddr) = temp_cp.peeraddr; |
1570 | } | | 1551 | } |
1571 | SET_PORT(&peeraddr, NTP_PORT); | | 1552 | SET_PORT(&peeraddr, NTP_PORT); |
1572 | #ifdef ISC_PLATFORM_HAVESALEN | | 1553 | #ifdef ISC_PLATFORM_HAVESALEN |
1573 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 1554 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
1574 | #endif | | 1555 | #endif |
1575 | found = 0; | | 1556 | found = 0; |
1576 | peer = NULL; | | 1557 | peer = NULL; |
1577 | | | 1558 | |
1578 | DPRINTF(1, ("searching for %s\n", stoa(&peeraddr))); | | 1559 | DPRINTF(1, ("searching for %s\n", stoa(&peeraddr))); |
1579 | | | 1560 | |
1580 | while (!found) { | | 1561 | while (!found) { |
1581 | peer = findexistingpeer(&peeraddr, peer, -1, 0); | | 1562 | peer = findexistingpeer(&peeraddr, peer, -1, 0); |
1582 | if (!peer) | | 1563 | if (!peer) |
1583 | break; | | 1564 | break; |
1584 | if (peer->flags & FLAG_CONFIG) | | 1565 | if (peer->flags & FLAG_CONFIG) |
1585 | found = 1; | | 1566 | found = 1; |
1586 | } | | 1567 | } |
1587 | if (!found) | | 1568 | if (!found) |
1588 | bad = 1; | | 1569 | bad = 1; |
1589 | cp = (struct conf_unpeer *) | | 1570 | datap += item_sz; |
1590 | ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1591 | } | | 1571 | } |
1592 | | | 1572 | |
1593 | if (bad) { | | 1573 | if (bad) { |
1594 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 1574 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
1595 | return; | | 1575 | return; |
1596 | } | | 1576 | } |
1597 | | | 1577 | |
1598 | /* | | 1578 | /* |
1599 | * Now do it in earnest. | | 1579 | * Now do it in earnest. |
1600 | */ | | 1580 | */ |
1601 | | | 1581 | |
1602 | items = INFO_NITEMS(inpkt->err_nitems); | | 1582 | items = INFO_NITEMS(inpkt->err_nitems); |
1603 | cp = (struct conf_unpeer *)inpkt->data; | | 1583 | datap = inpkt->data; |
1604 | | | 1584 | |
1605 | while (items-- > 0) { | | 1585 | while (items-- > 0) { |
1606 | memset(&temp_cp, 0, sizeof(temp_cp)); | | 1586 | memset(&temp_cp, 0, sizeof(temp_cp)); |
| | | 1587 | memcpy(&temp_cp, datap, item_sz); |
1607 | memset(&peeraddr, 0, sizeof(peeraddr)); | | 1588 | memset(&peeraddr, 0, sizeof(peeraddr)); |
1608 | memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1609 | if (client_v6_capable && temp_cp.v6_flag) { | | 1589 | if (client_v6_capable && temp_cp.v6_flag) { |
1610 | AF(&peeraddr) = AF_INET6; | | 1590 | AF(&peeraddr) = AF_INET6; |
1611 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; | | 1591 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; |
1612 | } else { | | 1592 | } else { |
1613 | AF(&peeraddr) = AF_INET; | | 1593 | AF(&peeraddr) = AF_INET; |
1614 | NSRCADR(&peeraddr) = temp_cp.peeraddr; | | 1594 | NSRCADR(&peeraddr) = temp_cp.peeraddr; |
1615 | } | | 1595 | } |
1616 | SET_PORT(&peeraddr, NTP_PORT); | | 1596 | SET_PORT(&peeraddr, NTP_PORT); |
1617 | #ifdef ISC_PLATFORM_HAVESALEN | | 1597 | #ifdef ISC_PLATFORM_HAVESALEN |
1618 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 1598 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
1619 | #endif | | 1599 | #endif |
1620 | found = 0; | | 1600 | found = 0; |
1621 | peer = NULL; | | 1601 | peer = NULL; |
| @@ -1623,28 +1603,27 @@ do_unconf( | | | @@ -1623,28 +1603,27 @@ do_unconf( |
1623 | while (!found) { | | 1603 | while (!found) { |
1624 | peer = findexistingpeer(&peeraddr, peer, -1, 0); | | 1604 | peer = findexistingpeer(&peeraddr, peer, -1, 0); |
1625 | if (!peer) | | 1605 | if (!peer) |
1626 | break; | | 1606 | break; |
1627 | if (peer->flags & FLAG_CONFIG) | | 1607 | if (peer->flags & FLAG_CONFIG) |
1628 | found = 1; | | 1608 | found = 1; |
1629 | } | | 1609 | } |
1630 | NTP_INSIST(found); | | 1610 | NTP_INSIST(found); |
1631 | NTP_INSIST(peer); | | 1611 | NTP_INSIST(peer); |
1632 | | | 1612 | |
1633 | peer_clear(peer, "GONE"); | | 1613 | peer_clear(peer, "GONE"); |
1634 | unpeer(peer); | | 1614 | unpeer(peer); |
1635 | | | 1615 | |
1636 | cp = (struct conf_unpeer *) | | 1616 | datap += item_sz; |
1637 | ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1638 | } | | 1617 | } |
1639 | | | 1618 | |
1640 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1619 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
1641 | } | | 1620 | } |
1642 | | | 1621 | |
1643 | | | 1622 | |
1644 | /* | | 1623 | /* |
1645 | * set_sys_flag - set system flags | | 1624 | * set_sys_flag - set system flags |
1646 | */ | | 1625 | */ |
1647 | static void | | 1626 | static void |
1648 | set_sys_flag( | | 1627 | set_sys_flag( |
1649 | sockaddr_u *srcadr, | | 1628 | sockaddr_u *srcadr, |
1650 | struct interface *inter, | | 1629 | struct interface *inter, |
| @@ -1858,199 +1837,115 @@ do_unrestrict( | | | @@ -1858,199 +1837,115 @@ do_unrestrict( |
1858 | | | 1837 | |
1859 | | | 1838 | |
1860 | /* | | 1839 | /* |
1861 | * do_restrict - do the dirty stuff of dealing with restrictions | | 1840 | * do_restrict - do the dirty stuff of dealing with restrictions |
1862 | */ | | 1841 | */ |
1863 | static void | | 1842 | static void |
1864 | do_restrict( | | 1843 | do_restrict( |
1865 | sockaddr_u *srcadr, | | 1844 | sockaddr_u *srcadr, |
1866 | struct interface *inter, | | 1845 | struct interface *inter, |
1867 | struct req_pkt *inpkt, | | 1846 | struct req_pkt *inpkt, |
1868 | int op | | 1847 | int op |
1869 | ) | | 1848 | ) |
1870 | { | | 1849 | { |
1871 | register struct conf_restrict *cr; | | 1850 | struct conf_restrict cr; |
1872 | register int items; | | 1851 | register int items; |
| | | 1852 | size_t item_sz; |
| | | 1853 | char * datap; |
1873 | sockaddr_u matchaddr; | | 1854 | sockaddr_u matchaddr; |
1874 | sockaddr_u matchmask; | | 1855 | sockaddr_u matchmask; |
1875 | int bad; | | 1856 | int bad; |
1876 | | | 1857 | |
1877 | /* | | 1858 | /* |
1878 | * Do a check of the flags to make sure that only | | 1859 | * Do a check of the flags to make sure that only |
1879 | * the NTPPORT flag is set, if any. If not, complain | | 1860 | * the NTPPORT flag is set, if any. If not, complain |
1880 | * about it. Note we are very picky here. | | 1861 | * about it. Note we are very picky here. |
1881 | */ | | 1862 | */ |
1882 | items = INFO_NITEMS(inpkt->err_nitems); | | 1863 | items = INFO_NITEMS(inpkt->err_nitems); |
1883 | cr = (struct conf_restrict *)inpkt->data; | | 1864 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
| | | 1865 | datap = inpkt->data; |
| | | 1866 | if (item_sz > sizeof(cr)) { |
| | | 1867 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 1868 | return; |
| | | 1869 | } |
1884 | | | 1870 | |
1885 | bad = 0; | | 1871 | bad = 0; |
1886 | cr->flags = ntohs(cr->flags); | | | |
1887 | cr->mflags = ntohs(cr->mflags); | | | |
1888 | while (items-- > 0 && !bad) { | | 1872 | while (items-- > 0 && !bad) { |
1889 | if (cr->mflags & ~(RESM_NTPONLY)) | | 1873 | memcpy(&cr, datap, item_sz); |
| | | 1874 | cr.flags = ntohs(cr.flags); |
| | | 1875 | cr.mflags = ntohs(cr.mflags); |
| | | 1876 | if (cr.mflags & ~(RESM_NTPONLY)) |
1890 | bad |= 1; | | 1877 | bad |= 1; |
1891 | if (cr->flags & ~(RES_ALLFLAGS)) | | 1878 | if (cr.flags & ~(RES_ALLFLAGS)) |
1892 | bad |= 2; | | 1879 | bad |= 2; |
1893 | if (cr->mask != htonl(INADDR_ANY)) { | | 1880 | if (cr.mask != htonl(INADDR_ANY)) { |
1894 | if (client_v6_capable && cr->v6_flag != 0) { | | 1881 | if (client_v6_capable && cr.v6_flag != 0) { |
1895 | if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6)) | | 1882 | if (IN6_IS_ADDR_UNSPECIFIED(&cr.addr6)) |
1896 | bad |= 4; | | 1883 | bad |= 4; |
1897 | } else | | 1884 | } else |
1898 | if (cr->addr == htonl(INADDR_ANY)) | | 1885 | if (cr.addr == htonl(INADDR_ANY)) |
1899 | bad |= 8; | | 1886 | bad |= 8; |
1900 | } | | 1887 | } |
1901 | cr = (struct conf_restrict *)((char *)cr + | | 1888 | datap += item_sz; |
1902 | INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1903 | } | | 1889 | } |
1904 | | | 1890 | |
1905 | if (bad) { | | 1891 | if (bad) { |
1906 | msyslog(LOG_ERR, "do_restrict: bad = %#x", bad); | | 1892 | msyslog(LOG_ERR, "do_restrict: bad = %#x", bad); |
1907 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1893 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
1908 | return; | | 1894 | return; |
1909 | } | | 1895 | } |
1910 | | | 1896 | |
1911 | /* | | 1897 | /* |
1912 | * Looks okay, try it out | | 1898 | * Looks okay, try it out |
1913 | */ | | 1899 | */ |
1914 | items = INFO_NITEMS(inpkt->err_nitems); | | | |
1915 | cr = (struct conf_restrict *)inpkt->data; | | | |
1916 | ZERO_SOCK(&matchaddr); | | 1900 | ZERO_SOCK(&matchaddr); |
1917 | ZERO_SOCK(&matchmask); | | 1901 | ZERO_SOCK(&matchmask); |
| | | 1902 | datap = inpkt->data; |
1918 | | | 1903 | |
1919 | while (items-- > 0) { | | 1904 | while (items-- > 0) { |
1920 | if (client_v6_capable && cr->v6_flag) { | | 1905 | memcpy(&cr, datap, item_sz); |
| | | 1906 | cr.flags = ntohs(cr.flags); |
| | | 1907 | cr.mflags = ntohs(cr.mflags); |
| | | 1908 | if (client_v6_capable && cr.v6_flag) { |
1921 | AF(&matchaddr) = AF_INET6; | | 1909 | AF(&matchaddr) = AF_INET6; |
1922 | AF(&matchmask) = AF_INET6; | | 1910 | AF(&matchmask) = AF_INET6; |
1923 | SOCK_ADDR6(&matchaddr) = cr->addr6; | | 1911 | SOCK_ADDR6(&matchaddr) = cr.addr6; |
1924 | SOCK_ADDR6(&matchmask) = cr->mask6; | | 1912 | SOCK_ADDR6(&matchmask) = cr.mask6; |
1925 | } else { | | 1913 | } else { |
1926 | AF(&matchaddr) = AF_INET; | | 1914 | AF(&matchaddr) = AF_INET; |
1927 | AF(&matchmask) = AF_INET; | | 1915 | AF(&matchmask) = AF_INET; |
1928 | NSRCADR(&matchaddr) = cr->addr; | | 1916 | NSRCADR(&matchaddr) = cr.addr; |
1929 | NSRCADR(&matchmask) = cr->mask; | | 1917 | NSRCADR(&matchmask) = cr.mask; |
1930 | } | | 1918 | } |
1931 | hack_restrict(op, &matchaddr, &matchmask, cr->mflags, | | 1919 | hack_restrict(op, &matchaddr, &matchmask, cr.mflags, |
1932 | cr->flags); | | 1920 | cr.flags); |
1933 | cr++; | | 1921 | datap += item_sz; |
1934 | } | | 1922 | } |
1935 | | | 1923 | |
1936 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1924 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
1937 | } | | 1925 | } |
1938 | | | 1926 | |
1939 | | | 1927 | |
1940 | /* | | 1928 | /* |
1941 | * mon_getlist - return monitor data | | 1929 | * mon_getlist - return monitor data |
1942 | */ | | 1930 | */ |
1943 | static void | | 1931 | static void |
1944 | mon_getlist_0( | | 1932 | mon_getlist( |
1945 | sockaddr_u *srcadr, | | | |
1946 | struct interface *inter, | | | |
1947 | struct req_pkt *inpkt | | | |
1948 | ) | | | |
1949 | { | | | |
1950 | register struct info_monitor *im; | | | |
1951 | register struct mon_data *md; | | | |
1952 | extern struct mon_data mon_mru_list; | | | |
1953 | extern int mon_enabled; | | | |
1954 | | | | |
1955 | #ifdef DEBUG | | | |
1956 | if (debug > 2) | | | |
1957 | printf("wants monitor 0 list\n"); | | | |
1958 | #endif | | | |
1959 | if (!mon_enabled) { | | | |
1960 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | | |
1961 | return; | | | |
1962 | } | | | |
1963 | im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt, | | | |
1964 | v6sizeof(struct info_monitor)); | | | |
1965 | for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; | | | |
1966 | md = md->mru_next) { | | | |
1967 | im->lasttime = htonl((u_int32)((current_time - | | | |
1968 | md->firsttime) / md->count)); | | | |
1969 | im->firsttime = htonl((u_int32)(current_time - md->lasttime)); | | | |
1970 | im->restr = htonl((u_int32)md->flags); | | | |
1971 | im->count = htonl((u_int32)(md->count)); | | | |
1972 | if (IS_IPV6(&md->rmtadr)) { | | | |
1973 | if (!client_v6_capable) | | | |
1974 | continue; | | | |
1975 | im->addr6 = SOCK_ADDR6(&md->rmtadr); | | | |
1976 | im->v6_flag = 1; | | | |
1977 | } else { | | | |
1978 | im->addr = NSRCADR(&md->rmtadr); | | | |
1979 | if (client_v6_capable) | | | |
1980 | im->v6_flag = 0; | | | |
1981 | } | | | |
1982 | im->port = md->rmtport; | | | |
1983 | im->mode = md->mode; | | | |
1984 | im->version = md->version; | | | |
1985 | im = (struct info_monitor *)more_pkt(); | | | |
1986 | } | | | |
1987 | flush_pkt(); | | | |
1988 | } | | | |
1989 | | | | |
1990 | /* | | | |
1991 | * mon_getlist - return monitor data | | | |
1992 | */ | | | |
1993 | static void | | | |
1994 | mon_getlist_1( | | | |
1995 | sockaddr_u *srcadr, | | 1933 | sockaddr_u *srcadr, |
1996 | struct interface *inter, | | 1934 | struct interface *inter, |
1997 | struct req_pkt *inpkt | | 1935 | struct req_pkt *inpkt |
1998 | ) | | 1936 | ) |
1999 | { | | 1937 | { |
2000 | register struct info_monitor_1 *im; | | 1938 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2001 | register struct mon_data *md; | | | |
2002 | extern struct mon_data mon_mru_list; | | | |
2003 | extern int mon_enabled; | | | |
2004 | | | | |
2005 | if (!mon_enabled) { | | | |
2006 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | | |
2007 | return; | | | |
2008 | } | | | |
2009 | im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt, | | | |
2010 | v6sizeof(struct info_monitor_1)); | | | |
2011 | for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; | | | |
2012 | md = md->mru_next) { | | | |
2013 | im->lasttime = htonl((u_int32)((current_time - | | | |
2014 | md->firsttime) / md->count)); | | | |
2015 | im->firsttime = htonl((u_int32)(current_time - md->lasttime)); | | | |
2016 | im->restr = htonl((u_int32)md->flags); | | | |
2017 | im->count = htonl((u_int32)md->count); | | | |
2018 | if (IS_IPV6(&md->rmtadr)) { | | | |
2019 | if (!client_v6_capable) | | | |
2020 | continue; | | | |
2021 | im->addr6 = SOCK_ADDR6(&md->rmtadr); | | | |
2022 | im->v6_flag = 1; | | | |
2023 | im->daddr6 = SOCK_ADDR6(&md->interface->sin); | | | |
2024 | } else { | | | |
2025 | im->addr = NSRCADR(&md->rmtadr); | | | |
2026 | if (client_v6_capable) | | | |
2027 | im->v6_flag = 0; | | | |
2028 | if (MDF_BCAST == md->cast_flags) | | | |
2029 | im->daddr = NSRCADR(&md->interface->bcast); | | | |
2030 | else if (md->cast_flags) { | | | |
2031 | im->daddr = NSRCADR(&md->interface->sin); | | | |
2032 | if (!im->daddr) | | | |
2033 | im->daddr = NSRCADR(&md->interface->bcast); | | | |
2034 | } else | | | |
2035 | im->daddr = 4; | | | |
2036 | } | | | |
2037 | im->flags = htonl(md->cast_flags); | | | |
2038 | im->port = md->rmtport; | | | |
2039 | im->mode = md->mode; | | | |
2040 | im->version = md->version; | | | |
2041 | im = (struct info_monitor_1 *)more_pkt(); | | | |
2042 | } | | | |
2043 | flush_pkt(); | | | |
2044 | } | | 1939 | } |
2045 | | | 1940 | |
2046 | /* | | 1941 | /* |
2047 | * Module entry points and the flags they correspond with | | 1942 | * Module entry points and the flags they correspond with |
2048 | */ | | 1943 | */ |
2049 | struct reset_entry { | | 1944 | struct reset_entry { |
2050 | int flag; /* flag this corresponds to */ | | 1945 | int flag; /* flag this corresponds to */ |
2051 | void (*handler) (void); /* routine to handle request */ | | 1946 | void (*handler) (void); /* routine to handle request */ |
2052 | }; | | 1947 | }; |
2053 | | | 1948 | |
2054 | struct reset_entry reset_entries[] = { | | 1949 | struct reset_entry reset_entries[] = { |
2055 | { RESET_FLAG_ALLPEERS, peer_all_reset }, | | 1950 | { RESET_FLAG_ALLPEERS, peer_all_reset }, |
2056 | { RESET_FLAG_IO, io_clr_stats }, | | 1951 | { RESET_FLAG_IO, io_clr_stats }, |
| @@ -2100,92 +1995,100 @@ reset_stats( | | | @@ -2100,92 +1995,100 @@ reset_stats( |
2100 | } | | 1995 | } |
2101 | | | 1996 | |
2102 | | | 1997 | |
2103 | /* | | 1998 | /* |
2104 | * reset_peer - clear a peer's statistics | | 1999 | * reset_peer - clear a peer's statistics |
2105 | */ | | 2000 | */ |
2106 | static void | | 2001 | static void |
2107 | reset_peer( | | 2002 | reset_peer( |
2108 | sockaddr_u *srcadr, | | 2003 | sockaddr_u *srcadr, |
2109 | struct interface *inter, | | 2004 | struct interface *inter, |
2110 | struct req_pkt *inpkt | | 2005 | struct req_pkt *inpkt |
2111 | ) | | 2006 | ) |
2112 | { | | 2007 | { |
2113 | struct conf_unpeer *cp; | | 2008 | struct conf_unpeer cp; |
2114 | int items; | | 2009 | int items; |
| | | 2010 | size_t item_sz; |
| | | 2011 | char * datap; |
2115 | struct peer *peer; | | 2012 | struct peer *peer; |
2116 | sockaddr_u peeraddr; | | 2013 | sockaddr_u peeraddr; |
2117 | int bad; | | 2014 | int bad; |
2118 | | | 2015 | |
2119 | /* | | 2016 | /* |
2120 | * We check first to see that every peer exists. If not, | | 2017 | * We check first to see that every peer exists. If not, |
2121 | * we return an error. | | 2018 | * we return an error. |
2122 | */ | | 2019 | */ |
2123 | | | 2020 | |
2124 | items = INFO_NITEMS(inpkt->err_nitems); | | 2021 | items = INFO_NITEMS(inpkt->err_nitems); |
2125 | cp = (struct conf_unpeer *)inpkt->data; | | 2022 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
| | | 2023 | datap = inpkt->data; |
| | | 2024 | if (item_sz > sizeof(cp)) { |
| | | 2025 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 2026 | return; |
| | | 2027 | } |
2126 | | | 2028 | |
2127 | bad = 0; | | 2029 | bad = 0; |
2128 | while (items-- > 0 && !bad) { | | 2030 | while (items-- > 0 && !bad) { |
| | | 2031 | memset(&cp,0,sizeof(cp)); |
| | | 2032 | memcpy(&cp, datap, item_sz); |
2129 | ZERO_SOCK(&peeraddr); | | 2033 | ZERO_SOCK(&peeraddr); |
2130 | if (client_v6_capable && cp->v6_flag) { | | 2034 | if (client_v6_capable && cp.v6_flag) { |
2131 | AF(&peeraddr) = AF_INET6; | | 2035 | AF(&peeraddr) = AF_INET6; |
2132 | SOCK_ADDR6(&peeraddr) = cp->peeraddr6; | | 2036 | SOCK_ADDR6(&peeraddr) = cp.peeraddr6; |
2133 | } else { | | 2037 | } else { |
2134 | AF(&peeraddr) = AF_INET; | | 2038 | AF(&peeraddr) = AF_INET; |
2135 | NSRCADR(&peeraddr) = cp->peeraddr; | | 2039 | NSRCADR(&peeraddr) = cp.peeraddr; |
2136 | } | | 2040 | } |
2137 | | | 2041 | |
2138 | #ifdef ISC_PLATFORM_HAVESALEN | | 2042 | #ifdef ISC_PLATFORM_HAVESALEN |
2139 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 2043 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
2140 | #endif | | 2044 | #endif |
2141 | peer = findexistingpeer(&peeraddr, NULL, -1, 0); | | 2045 | peer = findexistingpeer(&peeraddr, NULL, -1, 0); |
2142 | if (NULL == peer) | | 2046 | if (NULL == peer) |
2143 | bad++; | | 2047 | bad++; |
2144 | cp = (struct conf_unpeer *)((char *)cp + | | 2048 | datap += item_sz; |
2145 | INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
2146 | } | | 2049 | } |
2147 | | | 2050 | |
2148 | if (bad) { | | 2051 | if (bad) { |
2149 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2052 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2150 | return; | | 2053 | return; |
2151 | } | | 2054 | } |
2152 | | | 2055 | |
2153 | /* | | 2056 | /* |
2154 | * Now do it in earnest. | | 2057 | * Now do it in earnest. |
2155 | */ | | 2058 | */ |
2156 | | | 2059 | |
2157 | items = INFO_NITEMS(inpkt->err_nitems); | | 2060 | datap = inpkt->data; |
2158 | cp = (struct conf_unpeer *)inpkt->data; | | | |
2159 | while (items-- > 0) { | | 2061 | while (items-- > 0) { |
| | | 2062 | memset(&cp,0,sizeof(cp)); |
| | | 2063 | memcpy(&cp, datap, item_sz); |
2160 | ZERO_SOCK(&peeraddr); | | 2064 | ZERO_SOCK(&peeraddr); |
2161 | if (client_v6_capable && cp->v6_flag) { | | 2065 | if (client_v6_capable && cp.v6_flag) { |
2162 | AF(&peeraddr) = AF_INET6; | | 2066 | AF(&peeraddr) = AF_INET6; |
2163 | SOCK_ADDR6(&peeraddr) = cp->peeraddr6; | | 2067 | SOCK_ADDR6(&peeraddr) = cp.peeraddr6; |
2164 | } else { | | 2068 | } else { |
2165 | AF(&peeraddr) = AF_INET; | | 2069 | AF(&peeraddr) = AF_INET; |
2166 | NSRCADR(&peeraddr) = cp->peeraddr; | | 2070 | NSRCADR(&peeraddr) = cp.peeraddr; |
2167 | } | | 2071 | } |
2168 | SET_PORT(&peeraddr, 123); | | 2072 | SET_PORT(&peeraddr, 123); |
2169 | #ifdef ISC_PLATFORM_HAVESALEN | | 2073 | #ifdef ISC_PLATFORM_HAVESALEN |
2170 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 2074 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
2171 | #endif | | 2075 | #endif |
2172 | peer = findexistingpeer(&peeraddr, NULL, -1, 0); | | 2076 | peer = findexistingpeer(&peeraddr, NULL, -1, 0); |
2173 | while (peer != NULL) { | | 2077 | while (peer != NULL) { |
2174 | peer_reset(peer); | | 2078 | peer_reset(peer); |
2175 | peer = findexistingpeer(&peeraddr, peer, -1, 0); | | 2079 | peer = findexistingpeer(&peeraddr, peer, -1, 0); |
2176 | } | | 2080 | } |
2177 | cp = (struct conf_unpeer *)((char *)cp + | | 2081 | datap += item_sz; |
2178 | INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
2179 | } | | 2082 | } |
2180 | | | 2083 | |
2181 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 2084 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2182 | } | | 2085 | } |
2183 | | | 2086 | |
2184 | | | 2087 | |
2185 | /* | | 2088 | /* |
2186 | * do_key_reread - reread the encryption key file | | 2089 | * do_key_reread - reread the encryption key file |
2187 | */ | | 2090 | */ |
2188 | static void | | 2091 | static void |
2189 | do_key_reread( | | 2092 | do_key_reread( |
2190 | sockaddr_u *srcadr, | | 2093 | sockaddr_u *srcadr, |
2191 | struct interface *inter, | | 2094 | struct interface *inter, |
| @@ -2877,27 +2780,27 @@ fill_info_if_stats(void *data, interface | | | @@ -2877,27 +2780,27 @@ fill_info_if_stats(void *data, interface |
2877 | return; | | 2780 | return; |
2878 | } | | 2781 | } |
2879 | ifs->v6_flag = 1; | | 2782 | ifs->v6_flag = 1; |
2880 | ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin); | | 2783 | ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin); |
2881 | ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast); | | 2784 | ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast); |
2882 | ifs->unmask.addr6 = SOCK_ADDR6(&ep->mask); | | 2785 | ifs->unmask.addr6 = SOCK_ADDR6(&ep->mask); |
2883 | } else { | | 2786 | } else { |
2884 | ifs->v6_flag = 0; | | 2787 | ifs->v6_flag = 0; |
2885 | ifs->unaddr.addr = SOCK_ADDR4(&ep->sin); | | 2788 | ifs->unaddr.addr = SOCK_ADDR4(&ep->sin); |
2886 | ifs->unbcast.addr = SOCK_ADDR4(&ep->bcast); | | 2789 | ifs->unbcast.addr = SOCK_ADDR4(&ep->bcast); |
2887 | ifs->unmask.addr = SOCK_ADDR4(&ep->mask); | | 2790 | ifs->unmask.addr = SOCK_ADDR4(&ep->mask); |
2888 | } | | 2791 | } |
2889 | ifs->v6_flag = htonl(ifs->v6_flag); | | 2792 | ifs->v6_flag = htonl(ifs->v6_flag); |
2890 | strncpy(ifs->name, ep->name, sizeof(ifs->name)); | | 2793 | strlcpy(ifs->name, ep->name, sizeof(ifs->name)); |
2891 | ifs->family = htons(ep->family); | | 2794 | ifs->family = htons(ep->family); |
2892 | ifs->flags = htonl(ep->flags); | | 2795 | ifs->flags = htonl(ep->flags); |
2893 | ifs->last_ttl = htonl(ep->last_ttl); | | 2796 | ifs->last_ttl = htonl(ep->last_ttl); |
2894 | ifs->num_mcast = htonl(ep->num_mcast); | | 2797 | ifs->num_mcast = htonl(ep->num_mcast); |
2895 | ifs->received = htonl(ep->received); | | 2798 | ifs->received = htonl(ep->received); |
2896 | ifs->sent = htonl(ep->sent); | | 2799 | ifs->sent = htonl(ep->sent); |
2897 | ifs->notsent = htonl(ep->notsent); | | 2800 | ifs->notsent = htonl(ep->notsent); |
2898 | ifs->ifindex = htonl(ep->ifindex); | | 2801 | ifs->ifindex = htonl(ep->ifindex); |
2899 | /* scope no longer in struct interface, in in6_addr typically */ | | 2802 | /* scope no longer in struct interface, in in6_addr typically */ |
2900 | ifs->scopeid = ifs->ifindex; | | 2803 | ifs->scopeid = ifs->ifindex; |
2901 | ifs->ifnum = htonl(ep->ifnum); | | 2804 | ifs->ifnum = htonl(ep->ifnum); |
2902 | ifs->uptime = htonl(current_time - ep->starttime); | | 2805 | ifs->uptime = htonl(current_time - ep->starttime); |
2903 | ifs->ignore_packets = ep->ignore_packets; | | 2806 | ifs->ignore_packets = ep->ignore_packets; |