unsigned long in_netof(struct in_addr in) { unsigned long i, net; struct in_ifaddr *ia; /* Setup locals */ i = ntohl(in.s_addr); /* Get network number */ if ( IN_CLASSA(i) ) net = i & IN_CLASSA_NET; else if ( IN_CLASSB(i) ) net = i & IN_CLASSB_NET; else if ( IN_CLASSC(i) ) net = i & IN_CLASSC_NET; else if ( IN_CLASSD(i) ) net = i & IN_CLASSD_NET; else return 0; /* Check if subnet */ for (ia = in_ifaddr; ia != NULL; ia = ia->ia_next) if (net == ia->ia_net) return (i & ia->ia_subnetmask); return net; }
bool address::is_multicast() const { if (stor.ss_family == AF_INET6) return IN6_IS_ADDR_MULTICAST(&v6()->sin6_addr); else if (stor.ss_family == AF_INET) return IN_CLASSD(htonl(v4()->sin_addr.s_addr)); return false; }
/* * restrictions - return restrictions for this host */ u_short restrictions( sockaddr_u *srcadr ) { restrict_u *match; struct in6_addr *pin6; u_short flags; res_calls++; flags = 0; /* IPv4 source address */ if (IS_IPV4(srcadr)) { /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ if (IN_CLASSD(SRCADR(srcadr))) return (int)RES_IGNORE; match = match_restrict4_addr(SRCADR(srcadr), SRCPORT(srcadr)); match->count++; /* * res_not_found counts only use of the final default * entry, not any "restrict default ntpport ...", which * would be just before the final default. */ if (&restrict_def4 == match) res_not_found++; else res_found++; flags = match->flags; } /* IPv6 source address */ if (IS_IPV6(srcadr)) { pin6 = PSOCK_ADDR6(srcadr); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ if (IN6_IS_ADDR_MULTICAST(pin6)) return (int)RES_IGNORE; match = match_restrict6_addr(pin6, SRCPORT(srcadr)); match->count++; if (&restrict_def6 == match) res_not_found++; else res_found++; flags = match->flags; } return (flags); }
int nl_set_ifaddr(struct in_addr ifaddr, struct in_addr bcaddr, int ifindex) { struct { struct ifaddrmsg ifa; struct { struct rtattr rta; struct in_addr addr; } data[3]; } m; memset(&m, 0, sizeof(m)); m.ifa.ifa_family = AF_INET; if (IN_CLASSA(ifaddr.s_addr)) m.ifa.ifa_prefixlen = IN_CLASSA_NSHIFT; else if (IN_CLASSB(ifaddr.s_addr)) m.ifa.ifa_prefixlen = IN_CLASSB_NSHIFT; else if (IN_CLASSC(ifaddr.s_addr)) m.ifa.ifa_prefixlen = IN_CLASSC_NSHIFT; else if (IN_CLASSD(ifaddr.s_addr)) m.ifa.ifa_prefixlen = 0; m.ifa.ifa_prefixlen = 24; m.ifa.ifa_flags = 0; //IFA_F_PERMANENT; m.ifa.ifa_scope = RT_SCOPE_UNIVERSE; m.ifa.ifa_index = ifindex; m.data[0].rta.rta_len = RTA_LENGTH(sizeof(ifaddr)); m.data[0].rta.rta_type = IFA_LOCAL; m.data[0].addr.s_addr = ifaddr.s_addr; m.data[1].rta.rta_len = RTA_LENGTH(sizeof(ifaddr)); m.data[1].rta.rta_type = IFA_ADDRESS; m.data[1].addr.s_addr = ifaddr.s_addr; m.data[2].rta.rta_len = RTA_LENGTH(sizeof(ifaddr)); m.data[2].rta.rta_type = IFA_BROADCAST; m.data[2].addr.s_addr = bcaddr.s_addr; DEBUG(LOG_DEBUG, 0, "Sending new ifaddr %s %s netlink message index=%d", ip_to_str(ifaddr), ip_to_str(bcaddr), ifindex); return nl_create_and_send_msg(rtnlsock, RTM_NEWADDR, &m, sizeof(m)); }
void isis_circuit_add_addr (struct isis_circuit *circuit, struct connected *connected) { struct listnode *node; struct prefix_ipv4 *ipv4; u_char buf[BUFSIZ]; #ifdef HAVE_IPV6 struct prefix_ipv6 *ipv6; #endif /* HAVE_IPV6 */ memset (&buf, 0, BUFSIZ); if (connected->address->family == AF_INET) { u_int32_t addr = connected->address->u.prefix4.s_addr; addr = ntohl (addr); if (IPV4_NET0(addr) || IPV4_NET127(addr) || IN_CLASSD(addr) || IPV4_LINKLOCAL(addr)) return; for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ipv4)) if (prefix_same ((struct prefix *) ipv4, connected->address)) return; ipv4 = prefix_ipv4_new (); ipv4->prefixlen = connected->address->prefixlen; ipv4->prefix = connected->address->u.prefix4; listnode_add (circuit->ip_addrs, ipv4); /* Update MPLS TE Local IP address parameter */ set_circuitparams_local_ipaddr (circuit->mtc, ipv4->prefix); if (circuit->area) lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); #ifdef EXTREME_DEBUG prefix2str (connected->address, buf, BUFSIZ); zlog_debug ("Added IP address %s to circuit %d", buf, circuit->circuit_id); #endif /* EXTREME_DEBUG */ }
static void set_broadcast_address( uint32_t net_address) { #if defined(USE_INADDR) && USE_INADDR /* Note: sometimes INADDR_BROADCAST does not let me get any unicast messages. Not sure why... */ net_address = net_address; bip_set_broadcast_addr(INADDR_BROADCAST); #elif defined(USE_CLASSADDR) && USE_CLASSADDR long broadcast_address = 0; if (IN_CLASSA(ntohl(net_address))) broadcast_address = (ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST; else if (IN_CLASSB(ntohl(net_address))) broadcast_address = (ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST; else if (IN_CLASSC(ntohl(net_address))) broadcast_address = (ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST; else if (IN_CLASSD(ntohl(net_address))) broadcast_address = (ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST; else broadcast_address = INADDR_BROADCAST; bip_set_broadcast_addr(htonl(broadcast_address)); #else /* these are network byte order variables */ long broadcast_address = 0; long net_mask = 0; net_mask = getIpMaskForIpAddress(net_address); if (BIP_Debug) { struct in_addr address; address.s_addr = net_mask; printf("IP Mask: %s\n", inet_ntoa(address)); } broadcast_address = (net_address & net_mask) | (~net_mask); bip_set_broadcast_addr(broadcast_address); #endif }
static bool valid_reflector_address( const char *address ) { debug( "Validating an IPv4 address ( %s ).", address != NULL ? address : "" ); assert( address != NULL ); struct in_addr dst; int ret = inet_pton( AF_INET, address, &dst ); if ( ret != 1 ) { error( "Invalid IP address ( %s ).", address ); return false; } const uint32_t dst_addr = ntohl( dst.s_addr ); if ( ( IN_CLASSA( dst_addr ) && ( dst_addr != INADDR_ANY ) && ( dst_addr != INADDR_LOOPBACK ) ) || IN_CLASSB( dst_addr ) || IN_CLASSC( dst_addr ) || IN_CLASSD( dst_addr ) ) { debug( "Valid IPv4 address ( %s ).", address ); return true; } error( "Invalid IP address ( %s ).", address ); return false; }
/* * peer_config - configure a new association */ struct peer * peer_config( struct sockaddr_storage *srcadr, struct interface *dstadr, int hmode, int version, int minpoll, int maxpoll, u_int flags, int ttl, keyid_t key, u_char *keystr ) { register struct peer *peer; u_char cast_flags; /* * First search from the beginning for an association with given * remote address and mode. If an interface is given, search * from there to find the association which matches that * destination. If the given interface is "any", track down * the actual interface, because that's what gets put into the * peer structure. */ peer = findexistingpeer(srcadr, (struct peer *)0, hmode); if (dstadr != 0) { while (peer != 0) { if (peer->dstadr == dstadr) break; if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) && peer->dstadr == findinterface(srcadr)) break; peer = findexistingpeer(srcadr, peer, hmode); } } /* * We do a dirty little jig to figure the cast flags. This is * probably not the best place to do this, at least until the * configure code is rebuilt. Note only one flag can be set. */ switch (hmode) { case MODE_BROADCAST: if(srcadr->ss_family == AF_INET) { if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr))) cast_flags = MDF_MCAST; else cast_flags = MDF_BCAST; break; } else { if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr)) cast_flags = MDF_MCAST; else cast_flags = MDF_BCAST; break; } case MODE_CLIENT: if(srcadr->ss_family == AF_INET) { if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr))) cast_flags = MDF_ACAST; else cast_flags = MDF_UCAST; break; } else { if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr)) cast_flags = MDF_ACAST; else cast_flags = MDF_UCAST; break; } default: cast_flags = MDF_UCAST; } /* * If the peer is already configured, some dope has a duplicate * configureation entry or another dope is wiggling from afar. */ if (peer != 0) { peer->hmode = (u_char)hmode; peer->version = (u_char) version; peer->minpoll = (u_char) minpoll; peer->maxpoll = (u_char) maxpoll; peer->flags = flags | FLAG_CONFIG | (peer->flags & FLAG_REFCLOCK); peer->cast_flags = cast_flags; peer->ttl = (u_char) ttl; peer->keyid = key; peer->precision = sys_precision; peer_clear(peer, "RMOT"); return (peer); } /* * Here no match has been found, so presumably this is a new * persistent association. Mobilize the thing and initialize its * variables. If emulating ntpdate, force iburst. */ if (mode_ntpdate) flags |= FLAG_IBURST; peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, flags | FLAG_CONFIG, cast_flags, ttl, key); return (peer); }
const char *mynetworks(void) { static VSTRING *result; if (result == 0) { char *myname = "mynetworks"; INET_ADDR_LIST *my_addr_list; INET_ADDR_LIST *my_mask_list; unsigned long addr; unsigned long mask; struct in_addr net; int shift; int junk; int i; int mask_style; mask_style = name_mask("mynetworks mask style", mask_styles, var_mynetworks_style); /* * XXX Workaround: name_mask() needs a flags argument so that we can * require exactly one value, or we need to provide an API that is * dedicated for single-valued flags. */ for (i = 0, junk = mask_style; junk != 0; junk >>= 1) i += (junk & 1); if (i != 1) msg_fatal("bad %s value: %s; specify exactly one value", VAR_MYNETWORKS_STYLE, var_mynetworks_style); result = vstring_alloc(20); my_addr_list = own_inet_addr_list(); my_mask_list = own_inet_mask_list(); for (i = 0; i < my_addr_list->used; i++) { addr = ntohl(my_addr_list->addrs[i].s_addr); mask = ntohl(my_mask_list->addrs[i].s_addr); switch (mask_style) { /* * Natural mask. This is dangerous if you're customer of an * ISP who gave you a small portion of their network. */ case MASK_STYLE_CLASS: if (IN_CLASSA(addr)) { mask = IN_CLASSA_NET; shift = IN_CLASSA_NSHIFT; } else if (IN_CLASSB(addr)) { mask = IN_CLASSB_NET; shift = IN_CLASSB_NSHIFT; } else if (IN_CLASSC(addr)) { mask = IN_CLASSC_NET; shift = IN_CLASSC_NSHIFT; } else if (IN_CLASSD(addr)) { mask = IN_CLASSD_NET; shift = IN_CLASSD_NSHIFT; } else { msg_fatal("%s: bad address class: %s", myname, inet_ntoa(my_addr_list->addrs[i])); } break; /* * Subnet mask. This is safe, but breaks backwards * compatibility when used as default setting. */ case MASK_STYLE_SUBNET: for (junk = mask, shift = BITS_PER_ADDR; junk != 0; shift--, (junk <<= 1)) /* void */ ; break; /* * Host only. Do not relay authorize other hosts. */ case MASK_STYLE_HOST: mask = ~0; shift = 0; break; default: msg_panic("unknown mynetworks mask style: %s", var_mynetworks_style); } net.s_addr = htonl(addr & mask); vstring_sprintf_append(result, "%s/%d ", inet_ntoa(net), BITS_PER_ADDR - shift); } if (msg_verbose) msg_info("%s: %s", myname, vstring_str(result)); }
/* * restrictions - return restrictions for this host */ int restrictions( struct sockaddr_storage *srcadr, int at_listhead ) { struct restrictlist *rl; struct restrictlist *match = NULL; struct restrictlist6 *rl6; struct restrictlist6 *match6 = NULL; struct in6_addr hostaddr6; struct in6_addr hostservaddr6; u_int32 hostaddr; int flags = 0; int isntpport; res_calls++; if (srcadr->ss_family == AF_INET) { /* * We need the host address in host order. Also need to * know whether this is from the ntp port or not. */ hostaddr = SRCADR(srcadr); isntpport = (SRCPORT(srcadr) == NTP_PORT); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * later!) */ if (IN_CLASSD(SRCADR(srcadr))) return (int)RES_IGNORE; /* * Set match to first entry, which is default entry. * Work our way down from there. */ match = restrictlist; for (rl = match->next; rl != NULL && rl->addr <= hostaddr; rl = rl->next) if ((hostaddr & rl->mask) == rl->addr) { if ((rl->mflags & RESM_NTPONLY) && !isntpport) continue; match = rl; } match->count++; if (match == restrictlist) res_not_found++; else res_found++; flags = match->flags; } /* IPv6 source address */ if (srcadr->ss_family == AF_INET6) { /* * Need to know whether this is from the ntp port or * not. */ hostaddr6 = GET_INADDR6(*srcadr); isntpport = (ntohs(( (struct sockaddr_in6 *)srcadr)->sin6_port) == NTP_PORT); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * later!) */ if (IN6_IS_ADDR_MULTICAST(&hostaddr6)) return (int)RES_IGNORE; /* * Set match to first entry, which is default entry. * Work our way down from there. */ match6 = restrictlist6; for (rl6 = match6->next; rl6 != NULL && (memcmp(&(rl6->addr6), &hostaddr6, sizeof(hostaddr6)) <= 0); rl6 = rl6->next) { SET_IPV6_ADDR_MASK(&hostservaddr6, &hostaddr6, &rl6->mask6); if (memcmp(&hostservaddr6, &(rl6->addr6), sizeof(hostservaddr6)) == 0) { if ((rl6->mflags & RESM_NTPONLY) && !isntpport) continue; match6 = rl6; } } match6->count++; if (match6 == restrictlist6) res_not_found++; else res_found++; flags = match6->flags; } /* * The following implements a generalized call gap facility. * Douse the RES_LIMITED bit only if the interval since the last * packet is greater than res_min_interval and the average is * greater thatn res_avg_interval. */ if (!at_listhead || mon_enabled == MON_OFF) { flags &= ~RES_LIMITED; } else { struct mon_data *md; /* * At this poin the most recent arrival is first in the * MRU list. Let the first 10 packets in for free until * the average stabilizes. */ md = mon_mru_list.mru_next; if (md->avg_interval == 0) md->avg_interval = md->drop_count; else md->avg_interval += (md->drop_count - md->avg_interval) / RES_AVG; if (md->count < 10 || (md->drop_count > res_min_interval && md->avg_interval > res_avg_interval)) flags &= ~RES_LIMITED; md->drop_count = flags; } return (flags); }
//TODO:implementacia DNS int rtp_net_connect(char *ip, uint16_t rtp_port, struct rtp_session *session) { if(rtp_port % 2 != 0) //RTP port must be even goto ON_ERROR; //RTCP port must be RTP port + 1 struct sockaddr_in rtp_addr = { .sin_family = AF_INET, .sin_port = htons(rtp_port), .sin_addr.s_addr = inet_addr(ip) }; struct sockaddr_in rtcp_addr = { .sin_family = AF_INET, .sin_port = htons(rtp_port + 1), .sin_addr.s_addr = inet_addr(ip) }; //------------------------------------------------------ //skopirovane z RtpStore struct ip_mreq rtp_mreq; /* multicast group */ struct ip_mreq rtcp_mreq; if(ip) { rtp_mreq.imr_multiaddr = rtp_addr.sin_addr; rtp_mreq.imr_interface.s_addr = htonl(INADDR_ANY); rtp_addr.sin_addr = rtp_mreq.imr_multiaddr; rtcp_mreq.imr_multiaddr = rtcp_addr.sin_addr; rtcp_mreq.imr_interface.s_addr = htonl(INADDR_ANY); rtcp_addr.sin_addr = rtcp_mreq.imr_multiaddr; } /* unicast */ else { rtp_mreq.imr_multiaddr.s_addr = INADDR_ANY; rtp_addr.sin_addr.s_addr = INADDR_ANY; rtcp_mreq.imr_multiaddr.s_addr = INADDR_ANY; rtcp_addr.sin_addr.s_addr = INADDR_ANY; } //------------------------------------------------------ session->rtp_sockfd = socket(PF_INET, SOCK_DGRAM, 0); session->rtcp_sockfd = socket(PF_INET, SOCK_DGRAM, 0); if(session->rtp_sockfd == -1) { rtp_print_log(RTP_ERROR, "Rtp socket(ip=%s, port=%d) failed with errno=%d\n", ip, rtp_port, strerror(errno)); goto ON_ERROR; } if(session->rtcp_sockfd == -1) { rtp_print_log(RTP_ERROR, "Rtcp socket(ip=%s, port=%d) failed with errno=%d\n", ip, rtp_port + 1, strerror(errno)); goto ON_ERROR; } //setting nonblocking mod of sockets (see man 2 select - part bugs) set_socks_nonblock(session); //------------------------------------------------------ //skopirovane z RtpStore int one = 1; if(IN_CLASSD(ntohl(rtp_mreq.imr_multiaddr.s_addr))) setsockopt(session->rtp_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)); if(IN_CLASSD(ntohl(rtcp_mreq.imr_multiaddr.s_addr))) setsockopt(session->rtcp_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)); //----------------------------------------------------- //TODO:kontrola podla errno + kontrola parnosti, neparnosti portov if(bind(session->rtp_sockfd, (struct sockaddr *) &rtp_addr, sizeof(rtp_addr)) < 0) { rtp_print_log(RTP_ERROR, "RTP socket (ip=%s, port=%d) bind failed with errno=%s\n", ip, rtp_port, strerror(errno)); goto ON_ERROR; } if(bind(session->rtcp_sockfd, (struct sockaddr *) &rtcp_addr, sizeof(rtcp_addr)) < 0) { rtp_print_log(RTP_ERROR, "RTCP socket (ip=%s, port=%d) bind failed with errno=%s\n", ip, rtp_port + 1, strerror(errno)); goto ON_ERROR; } //------------------------------------------------------ //skopirovane z RtpStore if(IN_CLASSD(ntohl(rtp_mreq.imr_multiaddr.s_addr))) { if(setsockopt(session->rtp_sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&rtp_mreq, sizeof(rtp_mreq)) < 0) goto ON_ERROR; } if(IN_CLASSD(ntohl(rtcp_mreq.imr_multiaddr.s_addr))) { if(setsockopt(session->rtcp_sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&rtcp_mreq, sizeof(rtcp_mreq)) < 0) goto ON_ERROR; } //------------------------------------------------------ rtp_print_log(RTP_DEBUG, "Rtp session (ip=%s, rtp port=%d) net connect successed\n", ip, rtp_port); return 0; ON_ERROR: rtp_net_close(session); return -1; }
int addnet(register const char *str) { register char *cp; register int width; register u_int32_t n, m; register struct nets *np; char *cp2; char tstr[64]; if (strlen(str) > sizeof(tstr) - 1) return(0); if (nets_size <= 0) { nets_size = 8; nets = malloc(nets_size * sizeof(*nets)); } else if (nets_size <= nets_ind) { /* XXX debugging */ nets_size <<= 1; nets = realloc(nets, nets_size * sizeof(*nets)); } if (nets == NULL) { (void)fprintf(stderr, "%s: addnet: malloc/realloc: %s\n", prog, strerror(errno)); exit(1); } np = nets + nets_ind; width = 0; strcpy(tstr, str); cp = strchr(tstr, '/'); if (cp != NULL) { *cp++ = '\0'; width = strtol(cp, &cp2, 10); /* Trailing garbage */ if (*cp2 != '\0') return (0); if (width > 32) return (0); } /* XXX hack */ n = ntohl(inet_addr(tstr)); while ((n & 0xff000000) == 0) { n <<= 8; if (n == 0) return (0); } n = htonl(n); if (width != 0) { m = ~0; m <<= 32 - width; } else if (IN_CLASSA(n)) m = IN_CLASSA_NET; else if (IN_CLASSB(n)) m = IN_CLASSB_NET; else if (IN_CLASSC(n)) m = IN_CLASSC_NET; else if (IN_CLASSD(n)) m = IN_CLASSD_NET; else return (0); m = htonl(m); np->net = n; np->netmask = m; ++nets_ind; return (1); }
/* * restrictions - return restrictions for this host */ int restrictions( struct sockaddr_in *srcadr ) { register struct restrictlist *rl; register struct restrictlist *match; register u_int32 hostaddr; register int isntpport; res_calls++; /* * We need the host address in host order. Also need to know * whether this is from the ntp port or not. */ hostaddr = SRCADR(srcadr); isntpport = (SRCPORT(srcadr) == NTP_PORT); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, later!) */ if (IN_CLASSD(ntohl(srcadr->sin_addr.s_addr))) return (int)RES_IGNORE; /* * Set match to first entry, which is default entry. Work our * way down from there. */ match = restrictlist; for (rl = match->next; rl != 0 && rl->addr <= hostaddr; rl = rl->next) if ((hostaddr & rl->mask) == rl->addr) { if ((rl->mflags & RESM_NTPONLY) && !isntpport) continue; match = rl; } match->count++; if (match == restrictlist) res_not_found++; else res_found++; /* * The following implements limiting the number of clients * accepted from a given network. The notion of "same network" * is determined by the mask and addr fields of the restrict * list entry. The monitor mechanism has to be enabled for * collecting info on current clients. * * The policy is as follows: * - take the list of clients recorded * from the given "network" seen within the last * client_limit_period seconds * - if there are at most client_limit entries: * --> access allowed * - otherwise sort by time first seen * - current client among the first client_limit seen * hosts? * if yes: access allowed * else: eccess denied */ if (match->flags & RES_LIMITED) { int lcnt; struct mon_data *md, *this_client; #ifdef DEBUG if (debug > 2) printf("limited clients check: %ld clients, period %ld seconds, net is 0x%lX\n", client_limit, client_limit_period, (u_long)netof(hostaddr)); #endif /*DEBUG*/ if (mon_enabled == MON_OFF) { #ifdef DEBUG if (debug > 4) printf("no limit - monitoring is off\n"); #endif return (int)(match->flags & ~RES_LIMITED); } /* * How nice, MRU list provides our current client as the * first entry in the list. * Monitoring was verified to be active above, thus we * know an entry for our client must exist, or some * brain dead set the memory limit for mon entries to ZERO!!! */ this_client = mon_mru_list.mru_next; for (md = mon_fifo_list.fifo_next,lcnt = 0; md != &mon_fifo_list; md = md->fifo_next) { if ((current_time - md->lasttime) > client_limit_period) { #ifdef DEBUG if (debug > 5) printf("checking: %s: ignore: too old: %ld\n", numtoa(md->rmtadr), current_time - md->lasttime); #endif continue; } if (md->mode == MODE_BROADCAST || md->mode == MODE_CONTROL || md->mode == MODE_PRIVATE) { #ifdef DEBUG if (debug > 5) printf("checking: %s: ignore mode %d\n", numtoa(md->rmtadr), md->mode); #endif continue; } if (netof(md->rmtadr) != netof(hostaddr)) { #ifdef DEBUG if (debug > 5) printf("checking: %s: different net 0x%lX\n", numtoa(md->rmtadr), (u_long)netof(md->rmtadr)); #endif continue; } lcnt++; if (lcnt > (int) client_limit || md->rmtadr == hostaddr) { #ifdef DEBUG if (debug > 5) printf("considering %s: found host\n", numtoa(md->rmtadr)); #endif break; } #ifdef DEBUG else { if (debug > 5) printf("considering %s: same net\n", numtoa(md->rmtadr)); } #endif } #ifdef DEBUG if (debug > 4) printf("this one is rank %d in list, limit is %lu: %s\n", lcnt, client_limit, (lcnt <= (int) client_limit) ? "ALLOW" : "REJECT"); #endif if (lcnt <= (int) client_limit) { this_client->lastdrop = 0; return (int)(match->flags & ~RES_LIMITED); } else { this_client->lastdrop = current_time; } } return (int)match->flags; }
/* * loadservers - load list of NTP servers from configuration file */ void loadservers( char *cfgpath ) { register int i; int errflg; int peerversion; int minpoll; int maxpoll; /* int ttl; */ int srvcnt; /* u_long peerkey; */ int peerflags; struct sockaddr_in peeraddr; FILE *fp; char line[MAXLINE]; char *(tokens[MAXTOKENS]); int ntokens; int tok; const char *config_file; #ifdef SYS_WINNT char *alt_config_file; LPTSTR temp; char config_file_storage[MAX_PATH]; char alt_config_file_storage[MAX_PATH]; #endif /* SYS_WINNT */ struct server *server, *srvlist; /* * Initialize, initialize */ srvcnt = 0; srvlist = 0; errflg = 0; #ifdef DEBUG debug = 0; #endif /* DEBUG */ #ifndef SYS_WINNT config_file = cfgpath ? cfgpath : CONFIG_FILE; #else if (cfgpath) { config_file = cfgpath; } else { temp = CONFIG_FILE; if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) { msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n"); exit(1); } config_file = config_file_storage; } temp = ALT_CONFIG_FILE; if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) { msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n"); exit(1); } alt_config_file = alt_config_file_storage; M #endif /* SYS_WINNT */ if ((fp = fopen(FindConfig(config_file), "r")) == NULL) { fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(config_file)); msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(config_file)); #ifdef SYS_WINNT /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */ if ((fp = fopen(FindConfig(alt_config_file), "r")) == NULL) { /* * Broadcast clients can sometimes run without * a configuration file. */ fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(alt_config_file)); msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(alt_config_file)); return; } #else /* not SYS_WINNT */ return; #endif /* not SYS_WINNT */ } while ((tok = gettokens(fp, line, tokens, &ntokens)) != CONFIG_UNKNOWN) { switch(tok) { case CONFIG_PEER: case CONFIG_SERVER: if (ntokens < 2) { msyslog(LOG_ERR, "No address for %s, line ignored", tokens[0]); break; } if (!getnetnum(tokens[1], &peeraddr, 1)) { /* Resolve now, or lose! */ break; } else { errflg = 0; /* Shouldn't be able to specify multicast */ if (IN_CLASSD(ntohl(peeraddr.sin_addr.s_addr)) || ISBADADR(&peeraddr)) { msyslog(LOG_ERR, "attempt to configure invalid address %s", ntoa(&peeraddr)); break; } } peerversion = NTP_VERSION; minpoll = NTP_MINDPOLL; maxpoll = NTP_MAXDPOLL; /* peerkey = 0; */ peerflags = 0; /* ttl = 0; */ for (i = 2; i < ntokens; i++) switch (matchkey(tokens[i], mod_keywords)) { case CONF_MOD_VERSION: if (i >= ntokens-1) { msyslog(LOG_ERR, "peer/server version requires an argument"); errflg = 1; break; } peerversion = atoi(tokens[++i]); if ((u_char)peerversion > NTP_VERSION || (u_char)peerversion < NTP_OLDVERSION) { msyslog(LOG_ERR, "inappropriate version number %s, line ignored", tokens[i]); errflg = 1; } break; case CONF_MOD_KEY: if (i >= ntokens-1) { msyslog(LOG_ERR, "key: argument required"); errflg = 1; break; } ++i; /* peerkey = (int)atol(tokens[i]); */ peerflags |= FLAG_AUTHENABLE; break; case CONF_MOD_MINPOLL: if (i >= ntokens-1) { msyslog(LOG_ERR, "minpoll: argument required"); errflg = 1; break; } minpoll = atoi(tokens[++i]); if (minpoll < NTP_MINPOLL) minpoll = NTP_MINPOLL; break; case CONF_MOD_MAXPOLL: if (i >= ntokens-1) { msyslog(LOG_ERR, "maxpoll: argument required" ); errflg = 1; break; } maxpoll = atoi(tokens[++i]); if (maxpoll > NTP_MAXPOLL) maxpoll = NTP_MAXPOLL; break; case CONF_MOD_PREFER: peerflags |= FLAG_PREFER; break; case CONF_MOD_BURST: peerflags |= FLAG_BURST; break; case CONF_MOD_SKEY: peerflags |= FLAG_SKEY | FLAG_AUTHENABLE; break; case CONF_MOD_TTL: if (i >= ntokens-1) { msyslog(LOG_ERR, "ttl: argument required"); errflg = 1; break; } ++i; /* ttl = atoi(tokens[i]); */ break; case CONF_MOD_MODE: if (i >= ntokens-1) { msyslog(LOG_ERR, "mode: argument required"); errflg = 1; break; } ++i; /* ttl = atoi(tokens[i]); */ break; case CONFIG_UNKNOWN: errflg = 1; break; } if (minpoll > maxpoll) { msyslog(LOG_ERR, "config error: minpoll > maxpoll"); errflg = 1; } if (errflg == 0) { server = (struct server *)emalloc(sizeof(struct server)); memset((char *)server, 0, sizeof(struct server)); server->srcadr = peeraddr; server->version = peerversion; server->dispersion = PEER_MAXDISP; server->next_server = srvlist; srvlist = server; srvcnt++; } break; case CONFIG_KEYS: if (ntokens >= 2) { key_file = (char *) emalloc(strlen(tokens[1]) + 1); strcpy(key_file, tokens[1]); } break; } } (void) fclose(fp); /* build final list */ sys_numservers = srvcnt; sys_servers = (struct server **) emalloc(sys_numservers * sizeof(struct server *)); for(i=0;i<sys_numservers;i++) { sys_servers[i] = srvlist; srvlist = srvlist->next_server; } }
/* * restrictions - return restrictions for this host in *r4a */ void restrictions( sockaddr_u *srcadr, r4addr *r4a ) { restrict_u *match; struct in6_addr *pin6; REQUIRE(NULL != r4a); res_calls++; r4a->rflags = RES_IGNORE; r4a->ippeerlimit = 0; DPRINTF(1, ("restrictions: looking up %s\n", stoa(srcadr))); /* IPv4 source address */ if (IS_IPV4(srcadr)) { /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ if (IN_CLASSD(SRCADR(srcadr))) { DPRINTF(1, ("restrictions: srcadr %s is multicast\n", stoa(srcadr))); r4a->ippeerlimit = 2; /* XXX: we should use a better value */ return; } match = match_restrict4_addr(SRCADR(srcadr), SRCPORT(srcadr)); INSIST(match != NULL); match->count++; /* * res_not_found counts only use of the final default * entry, not any "restrict default ntpport ...", which * would be just before the final default. */ if (&restrict_def4 == match) res_not_found++; else res_found++; r4a->rflags = match->rflags; r4a->ippeerlimit = match->ippeerlimit; } /* IPv6 source address */ if (IS_IPV6(srcadr)) { pin6 = PSOCK_ADDR6(srcadr); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ if (IN6_IS_ADDR_MULTICAST(pin6)) return; match = match_restrict6_addr(pin6, SRCPORT(srcadr)); INSIST(match != NULL); match->count++; if (&restrict_def6 == match) res_not_found++; else res_found++; r4a->rflags = match->rflags; r4a->ippeerlimit = match->ippeerlimit; } return; }