Пример #1
0
/* Ask for routes
 * Do it only once to an interface, and not even after the interface
 * was broken and recovered.
 */
void
rip_query(void)
{
#ifdef _HAVE_SIN_LEN
	static struct sockaddr_in dst = {sizeof(dst), AF_INET, 0, {0}, {0}};
#else
	static struct sockaddr_in dst = {AF_INET};
#endif
	struct interface *ifp;
	struct rip buf;
	enum output_type type;


	if (rip_sock < 0)
		return;

	memset(&buf, 0, sizeof(buf));

	for (ifp = ifnet; ifp; ifp = ifp->int_next) {
		/* Skip interfaces those already queried.
		 * Do not ask via interfaces through which we don't
		 * accept input.  Do not ask via interfaces that cannot
		 * send RIP packets.
		 * Do try broken interfaces to see if they have healed.
		 */
		if (IS_RIP_IN_OFF(ifp->int_state)
		    || ifp->int_query_time != NEVER)
			continue;

		/* skip turned off interfaces */
		if (!iff_up(ifp->int_if_flags))
			continue;

		buf.rip_vers = (ifp->int_state&IS_NO_RIPV1_OUT) ? RIPv2:RIPv1;
		buf.rip_cmd = RIPCMD_REQUEST;
		buf.rip_nets[0].n_family = RIP_AF_UNSPEC;
		buf.rip_nets[0].n_metric = htonl(HOPCNT_INFINITY);

		/* Send a RIPv1 query only if allowed and if we will
		 * listen to RIPv1 routers.
		 */
		if ((ifp->int_state & IS_NO_RIPV1_OUT)
		    || (ifp->int_state & IS_NO_RIPV1_IN)) {
			buf.rip_vers = RIPv2;
		} else {
			buf.rip_vers = RIPv1;
		}

		if (ifp->int_if_flags & IFF_BROADCAST) {
			/* ordinary, hardware interface */
			dst.sin_addr.s_addr = ifp->int_brdaddr;

			/* Broadcast RIPv1 queries and RIPv2 queries
			 * when the hardware cannot multicast.
			 */
			if (buf.rip_vers == RIPv2
			    && (ifp->int_if_flags & IFF_MULTICAST)
			    && !(ifp->int_state  & IS_NO_RIP_MCAST)) {
				type = OUT_MULTICAST;
			} else {
				type = OUT_BROADCAST;
			}

		} else if (ifp->int_if_flags & IFF_POINTOPOINT) {
			/* point-to-point hardware interface */
			dst.sin_addr.s_addr = ifp->int_dstaddr;
			type = OUT_UNICAST;

		} else if (ifp->int_state & IS_REMOTE) {
			/* remote interface */
			dst.sin_addr.s_addr = ifp->int_addr;
			type = OUT_UNICAST;

		} else {
			/* ATM, HIPPI, etc. */
			continue;
		}

		ifp->int_query_time = now.tv_sec+SUPPLY_INTERVAL;
		if (output(type, &dst, ifp, &buf, sizeof(buf)) < 0)
			if_sick(ifp);
	}
}
Пример #2
0
/* use configured parameters */
void
get_parms(struct interface *ifp)
{
	static boolean_t warned_auth_in, warned_auth_out;
	struct parm *parmp;
	int i, num_passwds = 0;

	if (ifp == NULL)
		return;

	/* get all relevant parameters */
	for (parmp = parms; parmp != NULL; parmp = parmp->parm_next) {
		if (parmp->parm_name[0] == '\0' ||
		    strcmp(ifp->int_name, parmp->parm_name) == 0 ||
		    (parmp->parm_name[0] == '\n' &&
			on_net(ifp->int_addr,
			    parmp->parm_net, parmp->parm_mask))) {

			/*
			 * This group of parameters is relevant,
			 * so get its settings
			 */
			ifp->int_state |= parmp->parm_int_state;
			for (i = 0; i < MAX_AUTH_KEYS; i++) {
				if (parmp->parm_auth[i].type == RIP_AUTH_NONE ||
				    num_passwds >= MAX_AUTH_KEYS)
					break;
				ifp->int_auth[num_passwds++] =
				    parmp->parm_auth[i];
			}
			if (parmp->parm_rdisc_pref != 0)
				ifp->int_rdisc_pref = parmp->parm_rdisc_pref;
			if (parmp->parm_rdisc_int != 0)
				ifp->int_rdisc_int = parmp->parm_rdisc_int;
			if (parmp->parm_d_metric != 0)
				ifp->int_d_metric = parmp->parm_d_metric;
			if (parmp->parm_ripout_addr != 0)
				ifp->int_ripout_addr = parmp->parm_ripout_addr;
		}
	}

	/*
	 * Set general defaults.
	 *
	 * Default poor-man's router discovery to a metric that will
	 * be heard by old versions of `routed`.  They ignored received
	 * routes with metric 15.
	 */
	if ((ifp->int_state & IS_PM_RDISC) && ifp->int_d_metric == 0)
		ifp->int_d_metric = FAKE_METRIC;

	if (ifp->int_rdisc_int == 0)
		ifp->int_rdisc_int = DEF_MAXADVERTISEINTERVAL;

	if (!(ifp->int_if_flags & IFF_MULTICAST) &&
	    !(ifp->int_state & IS_REMOTE))
		ifp->int_state |= IS_BCAST_RDISC;

	if (ifp->int_if_flags & IFF_POINTOPOINT) {
		ifp->int_state |= IS_BCAST_RDISC;
		/*
		 * By default, point-to-point links should be passive
		 * about router-discovery for the sake of demand-dialing.
		 */
		if (!(ifp->int_state & GROUP_IS_SOL_OUT))
			ifp->int_state |= IS_NO_SOL_OUT;
		if (!(ifp->int_state & GROUP_IS_ADV_OUT))
			ifp->int_state |= IS_NO_ADV_OUT;
	}

	if (0 != (ifp->int_state & (IS_PASSIVE | IS_REMOTE)))
		ifp->int_state |= IS_NO_RDISC;
	if (ifp->int_state & IS_PASSIVE)
		ifp->int_state |= IS_NO_RIP;

	if (!IS_RIP_IN_OFF(ifp->int_state) &&
	    ifp->int_auth[0].type != RIP_AUTH_NONE &&
	    !(ifp->int_state & IS_NO_RIPV1_IN) && !warned_auth_in) {
		writelog(LOG_WARNING, "RIPv1 input via %s"
		    " will be accepted without authentication",
		    ifp->int_name);
		warned_auth_in = _B_TRUE;
	}
	if (!IS_RIP_OUT_OFF(ifp->int_state) &&
	    ifp->int_auth[0].type != RIP_AUTH_NONE &&
	    !(ifp->int_state & IS_NO_RIPV1_OUT)) {
		if (!warned_auth_out) {
			writelog(LOG_WARNING, "RIPv1 output via %s"
			    " will be sent without authentication",
			    ifp->int_name);
			warned_auth_out = _B_TRUE;
		}
	}

	/*
	 * If not overriden by the rip_neighbor option, set the
	 * default address to which RIP packets will be sent on
	 * this interface.
	 */
	if (ifp->int_ripout_addr == 0) {
		if (ifp->int_state & IS_REMOTE) {
			/*
			 * By definition we always send RIP packets to
			 * the address assigned to a remote interface.
			 */
			ifp->int_ripout_addr = ifp->int_addr;
		} else if ((ifp->int_state & IS_NO_RIPV1_OUT) &&
		    (ifp->int_if_flags & IFF_MULTICAST) &&
		    !(ifp->int_state & IS_NO_RIP_MCAST)) {
			/*
			 * If the interface is being used for RIPv2
			 * and it supports multicast, and if the user
			 * has not explicitely turned off multicast
			 * RIP output, send to the all RIP routers
			 * multicast address.
			 */
			ifp->int_ripout_addr = htonl(INADDR_RIP_GROUP);
		} else if (ifp->int_if_flags & IFF_POINTOPOINT) {
			/*
			 * For point-to-point interfaces which don't
			 * fall into the two categories above, just
			 * send to the destination address of the
			 * interface.
			 */
			ifp->int_ripout_addr = ifp->int_dstaddr;
		} else {
			/* Otherwise, use the broadcast address. */
			ifp->int_ripout_addr = ifp->int_brdaddr;
		}
	}
}