Ejemplo n.º 1
0
/**
 * parse_default_igmp_querier_timeout - Parse default_igmp_querier_timeout option
 * @s: String token
 *
 * Reads and assigns default querier timeout for an active IGMP querier.
 * This is the time it takes before pimd tries to take over as the
 * active querier.  If the argument is missing or invalid the system
 * will calculate a fallback based on the query interval.
 *
 * Syntax:
 * default_igmp_querier_timeout <SEC>
 *
 * Returns:
 * When parsing @s is successful this function returns %TRUE, otherwise %FALSE.
 */
static int parse_default_igmp_querier_timeout(char *s)
{
    char *w;
    uint32_t value = 0;
    uint32_t recommended = QUERIER_TIMEOUT(default_igmp_query_interval);

    if (EQUAL((w = next_word(&s)), "")) {
	WARN("Missing argument to default_igmp_querier_timeout!");
    } else if (sscanf(w, "%u", &value) != 1) {
	WARN("Invalid default default_igmp_querier_timeout!");
	value = 0;
    }

    /* Do some sanity checks to prevent invalid configuration and to recommend
     * better settings, see GitHub issue troglobit/pimd#31 for details. */
    if (value != 0) {
	/* 1) Prevent invalid configuration */
	if (value <= default_igmp_query_interval) {
	    WARN("IGMP querier timeout %d must be larger than the query interval %d, forcing default!",
		 value, default_igmp_query_interval);
	    value = recommended;
	}

	/* 2) Warn power user of potentially too low setting. */
	if (value < recommended)
	    WARN("The IGMP querier timeout %d is smaller than the recommended value %d, allowing ...",
		 value, recommended);

	logit(LOG_WARNING, 0, "Recommended querier timeout = Robustness x query-interval + response-time / 2 = %d x %d + %d / 2 = %d",
	      IGMP_ROBUSTNESS_VARIABLE, default_igmp_query_interval, IGMP_QUERY_RESPONSE_INTERVAL, recommended);
    }

    default_igmp_querier_timeout = value;

    return TRUE;
}
Ejemplo n.º 2
0
void config_vifs_from_file(void)
{
    FILE *f;
    char linebuf[LINE_BUFSIZ];
    char *w, *s;
    struct ifconf ifc;
    int option;
    char ifbuf[BUFSIZ];
    u_int8 *data_ptr;
    int error_flag;

    error_flag = FALSE;
    lineno = 0;

    if ((f = fopen(config_file, "r")) == NULL) {
	if (errno != ENOENT)
	    logit(LOG_WARNING, errno, "Cannot open %s", config_file);
	return;
    }

    /* TODO: HARDCODING!!! */
    cand_rp_adv_message.buffer = calloc(1, 4 + sizeof(pim_encod_uni_addr_t) +
					255 * sizeof(pim_encod_grp_addr_t));
    if (!cand_rp_adv_message.buffer)
	logit(LOG_ERR, errno, "Ran out of memory in config_vifs_from_file()");

    cand_rp_adv_message.prefix_cnt_ptr  = cand_rp_adv_message.buffer;
    /* By default, if no group_prefix configured, then prefix_cnt == 0
     * implies group_prefix = 224.0.0.0 and masklen = 4.
     */
    *cand_rp_adv_message.prefix_cnt_ptr = 0;
    cand_rp_adv_message.insert_data_ptr = cand_rp_adv_message.buffer;
    /* TODO: XXX: HARDCODING!!! */
    cand_rp_adv_message.insert_data_ptr += (4 + 6);

    ifc.ifc_buf = ifbuf;
    ifc.ifc_len = sizeof(ifbuf);
    if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
	logit(LOG_ERR, errno, "Failed querying kernel network interfaces");

    while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
	if (strlen(linebuf) >= (LINE_BUFSIZ - 1)) {
	    WARN("Line length must be shorter than %d", LINE_BUFSIZ);
	    error_flag = TRUE;
	}
	lineno++;

	s = linebuf;
	w = next_word(&s);
	option = parse_option(w);

	switch (option) {
	    case CONF_EMPTY:
		continue;
		break;

	    case CONF_PHYINT:
		parse_phyint(s);
		break;

	    case CONF_CANDIDATE_RP:
		parse_candidateRP(s);
		break;

	    case CONF_RP_ADDRESS:
		parse_rp_address(s);
		break;

	    case CONF_GROUP_PREFIX:
		parse_group_prefix(s);
		break;

	    case CONF_BOOTSTRAP_RP:
		parseBSR(s);
		break;

	    case CONF_COMPAT_THRESHOLD:
		parse_compat_threshold(s);
		break;

	    case CONF_SPT_THRESHOLD:
		parse_spt_threshold(s);
		break;

	    case CONF_DEFAULT_SOURCE_METRIC:
		parse_default_source_metric(s);
		break;

	    case CONF_DEFAULT_SOURCE_PREFERENCE:
		parse_default_source_preference(s);
		break;

	    case CONF_DEFAULT_IGMP_QUERY_INTERVAL:
		parse_default_igmp_query_interval(s);
		break;

	    case CONF_DEFAULT_IGMP_QUERIER_TIMEOUT:
		parse_default_igmp_querier_timeout(s);
		break;

	    default:
		logit(LOG_WARNING, 0, "%s:%u - Unknown command '%s'", config_file, lineno, w);
		error_flag = TRUE;
	}
    }

    if (error_flag)
	logit(LOG_ERR, 0, "%s:%u - Syntax error", config_file, lineno);

    cand_rp_adv_message.message_size = cand_rp_adv_message.insert_data_ptr - cand_rp_adv_message.buffer;
    if (cand_rp_flag != FALSE) {
	/* Prepare the RP info */
	my_cand_rp_holdtime = 2.5 * my_cand_rp_adv_period;

	/* TODO: HARDCODING! */
	data_ptr = cand_rp_adv_message.buffer + 1;
	PUT_BYTE(my_cand_rp_priority, data_ptr);
	PUT_HOSTSHORT(my_cand_rp_holdtime, data_ptr);
	PUT_EUADDR(my_cand_rp_address, data_ptr);
    }

    /* If no IGMP querier timeout was set, calculate from query interval */
    if (!default_igmp_querier_timeout)
	default_igmp_querier_timeout = QUERIER_TIMEOUT(default_igmp_query_interval);

    IF_DEBUG(DEBUG_IGMP) {
	logit(LOG_INFO, 0, "IGMP query interval  : %u sec", default_igmp_query_interval);
	logit(LOG_INFO, 0, "IGMP querier timeout : %u sec", default_igmp_querier_timeout);
    }

    fclose(f);
}
Ejemplo n.º 3
0
Archivo: config.c Proyecto: ViToni/pimd
void config_vifs_from_file(void)
{
    FILE *fp;
    char linebuf[LINE_BUFSIZ];
    char *w, *s;
    int option;
    uint8_t *data_ptr;
    int error_flag;

    error_flag = FALSE;
    lineno = 0;

    /* TODO: HARDCODING!!! */
    cand_rp_adv_message.buffer = calloc(1, 4 + sizeof(pim_encod_uni_addr_t) +
					255 * sizeof(pim_encod_grp_addr_t));
    if (!cand_rp_adv_message.buffer)
	logit(LOG_ERR, errno, "Ran out of memory in config_vifs_from_file()");

    cand_rp_adv_message.prefix_cnt_ptr  = cand_rp_adv_message.buffer;
    /* By default, if no group-prefix configured, then prefix_cnt == 0
     * implies group-prefix = 224.0.0.0 and masklen = 4.
     */
    *cand_rp_adv_message.prefix_cnt_ptr = 0;
    cand_rp_adv_message.insert_data_ptr = cand_rp_adv_message.buffer;
    /* TODO: XXX: HARDCODING!!! */
    cand_rp_adv_message.insert_data_ptr += (4 + 6);

    fp = fopen(config_file, "r");
    if (!fp) {
	logit(LOG_WARNING, errno, "Cannot open configuration file %s", config_file);
	fallback_config();
	goto nofile;
    }

    while (fgets(linebuf, sizeof(linebuf), fp)) {
	if (strlen(linebuf) >= (LINE_BUFSIZ - 1)) {
	    WARN("Line length must be shorter than %d", LINE_BUFSIZ);
	    error_flag = TRUE;
	}
	lineno++;

	s = linebuf;
	w = next_word(&s);
	option = parse_option(w);

	switch (option) {
	    case CONF_EMPTY:
		continue;
		break;

	    case CONF_PHYINT:
		parse_phyint(s);
		break;

	    case CONF_CANDIDATE_RP:
		parse_rp_candidate(s);
		break;

	    case CONF_RP_ADDRESS:
		parse_rp_address(s);
		break;

	    case CONF_GROUP_PREFIX:
		parse_group_prefix(s);
		break;

	    case CONF_BOOTSTRAP_RP:
		parse_bsr_candidate(s);
		break;

	    case CONF_COMPAT_THRESHOLD:
		parse_compat_threshold(s);
		break;

	    case CONF_SPT_THRESHOLD:
		parse_spt_threshold(s);
		break;

	    case CONF_DEFAULT_ROUTE_METRIC:
		parse_default_route_metric(s);
		break;

	    case CONF_DEFAULT_ROUTE_DISTANCE:
		parse_default_route_distance(s);
		break;

	    case CONF_IGMP_QUERY_INTERVAL:
		parse_igmp_query_interval(s);
		break;

	    case CONF_IGMP_QUERIER_TIMEOUT:
		parse_igmp_querier_timeout(s);
		break;

	    case CONF_HELLO_INTERVAL:
		parse_hello_interval(s);
		break;

	    default:
		logit(LOG_WARNING, 0, "%s:%u - Unknown command '%s'", config_file, lineno, w);
		error_flag = TRUE;
	}
    }

    fclose(fp);

  nofile:
    /* A static RP address is needed for SSM.  We use a link-local
     * address. It is not required to be configured on any interface. */
    strncpy(linebuf, "169.254.0.1 232.0.0.0/8\n", sizeof(linebuf));
    s = linebuf;
    parse_rp_address(s);

    if (error_flag)
	logit(LOG_ERR, 0, "%s:%u - Syntax error", config_file, lineno);

    cand_rp_adv_message.message_size = cand_rp_adv_message.insert_data_ptr - cand_rp_adv_message.buffer;
    if (cand_rp_flag != FALSE) {
	/* Prepare the RP info */
	my_cand_rp_holdtime = 2.5 * my_cand_rp_adv_period;

	/* TODO: HARDCODING! */
	data_ptr = cand_rp_adv_message.buffer + 1;
	PUT_BYTE(my_cand_rp_priority, data_ptr);
	PUT_HOSTSHORT(my_cand_rp_holdtime, data_ptr);
	PUT_EUADDR(my_cand_rp_address, data_ptr);
    }

    /* If no IGMP querier timeout was set, calculate from query interval */
    if (!igmp_querier_timeout)
	igmp_querier_timeout = QUERIER_TIMEOUT(igmp_query_interval);

    IF_DEBUG(DEBUG_IGMP) {
	logit(LOG_INFO, 0, "IGMP query interval  : %u sec", igmp_query_interval);
	logit(LOG_INFO, 0, "IGMP querier timeout : %u sec", igmp_querier_timeout);
    }
}