Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #4
0
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));
}
Beispiel #5
0
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;
}
Beispiel #8
0
/*
 * 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);
}
Beispiel #9
0
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));
    }
Beispiel #10
0
/*
 * 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);
}
Beispiel #11
0
//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;
}
Beispiel #12
0
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;
}
Beispiel #14
0
/*
 * 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;
	}
}
Beispiel #15
0
/*
 * 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;
}