int olsrd_sanity_check_cnf(struct olsrd_config *cnf) { struct olsr_if *in = cnf->interfaces; struct if_config_options *io; /* Debug level */ if (cnf->debug_level < MIN_DEBUGLVL || cnf->debug_level > MAX_DEBUGLVL) { fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level); return -1; } /* IP version */ if (cnf->ip_version != AF_INET && cnf->ip_version != AF_INET6) { fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version); return -1; } /* TOS */ if (cnf->tos > MAX_TOS) { fprintf(stderr, "TOS %d is not allowed\n", cnf->tos); return -1; } if (cnf->willingness_auto == false && (cnf->willingness > MAX_WILLINGNESS)) { fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness); return -1; } /* Hysteresis */ if (cnf->use_hysteresis == true) { if (cnf->hysteresis_param.scaling < MIN_HYST_PARAM || cnf->hysteresis_param.scaling > MAX_HYST_PARAM) { fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", cnf->hysteresis_param.scaling); return -1; } if (cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low) { fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low); return -1; } if (cnf->hysteresis_param.thr_high < MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > MAX_HYST_PARAM) { fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_high); return -1; } if (cnf->hysteresis_param.thr_low < MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > MAX_HYST_PARAM) { fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", cnf->hysteresis_param.thr_low); return -1; } } /* Pollrate */ if (cnf->pollrate < MIN_POLLRATE || cnf->pollrate > MAX_POLLRATE) { fprintf(stderr, "Pollrate %0.2f is not allowed\n", cnf->pollrate); return -1; } /* NIC Changes Pollrate */ if (cnf->nic_chgs_pollrate < MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > MAX_NICCHGPOLLRT) { fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", cnf->nic_chgs_pollrate); return -1; } /* TC redundancy */ if (cnf->tc_redundancy != 2) { fprintf(stderr, "Sorry, tc-redundancy 0/1 are not working on 0.5.6. " "It was discovered late in the stable tree development and cannot " "be solved without a difficult change in the dijkstra code. " "Feel free to contact the olsr-user mailinglist " "(http://www.olsr.org/?q=mailing-lists) to learn more " "about the problem. The next version of OLSR will have working " "tc-redundancy again.\n"); return -1; } /* MPR coverage */ if (cnf->mpr_coverage < MIN_MPR_COVERAGE || cnf->mpr_coverage > MAX_MPR_COVERAGE) { fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage); return -1; } /* Link Q and hysteresis cannot be activated at the same time */ if (cnf->use_hysteresis == true && cnf->lq_level) { fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n"); return -1; } /* Link quality level */ if (cnf->lq_level != 0 && cnf->lq_level != 2) { fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level); return -1; } /* Link quality window size */ if (cnf->lq_level && (cnf->lq_aging < MIN_LQ_AGING || cnf->lq_aging > MAX_LQ_AGING)) { fprintf(stderr, "LQ aging factor %f is not allowed\n", cnf->lq_aging); return -1; } /* NAT threshold value */ if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1 || cnf->lq_nat_thresh > 1.0)) { fprintf(stderr, "NAT threshold %f is not allowed\n", cnf->lq_nat_thresh); return -1; } #if defined linux #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) if (cnf->ip_version == AF_INET6 && cnf->smart_gw_active) { fprintf(stderr, "Smart gateways are not supported for linux kernel 2.4 and ipv6\n"); return -1; } #endif /* this rtpolicy settings are also currently only used in Linux */ if (olsrd_sanity_check_rtpolicy(cnf)) { return -1; } #endif if (in == NULL) { fprintf(stderr, "No interfaces configured!\n"); return -1; } if (cnf->min_tc_vtime < 0.0) { fprintf(stderr, "Error, negative minimal tc time not allowed.\n"); return -1; } if (cnf->min_tc_vtime > 0.0) { fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n"); } if (cnf->smart_gw_type >= GW_UPLINK_CNT) { fprintf(stderr, "Error, illegal gateway uplink type: %d\n", cnf->smart_gw_type); return -1; } if (cnf->smart_gw_downlink < MIN_SMARTGW_SPEED || cnf->smart_gw_downlink > MAX_SMARTGW_SPEED) { fprintf(stderr, "Error, bad gateway downlink speed: %d kbit/s (should be %d-%d)\n", cnf->smart_gw_downlink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED); return -1; } if (cnf->smart_gw_uplink < MIN_SMARTGW_SPEED || cnf->smart_gw_uplink > MAX_SMARTGW_SPEED) { fprintf(stderr, "Error, bad gateway uplink speed: %d kbit/s (should be %d-%d)\n", cnf->smart_gw_uplink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED); return -1; } if (cnf->interface_defaults == NULL) { /* get a default configuration if the user did not specify one */ cnf->interface_defaults = get_default_if_config(); } else { olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, false); olsrd_sanity_check_interface_cnf(cnf->interface_defaults, cnf, interface_defaults_name); } /* Interfaces */ while (in) { struct olsr_lq_mult *mult, *mult_orig; io = in->cnf; olsrd_print_interface_cnf(in->cnf, in->cnfi, false); /*apply defaults*/ { size_t pos; struct olsr_lq_mult *mult_temp, *mult_orig_walk; uint8_t *cnfptr = (uint8_t*)in->cnf; uint8_t *cnfiptr = (uint8_t*)in->cnfi; uint8_t *defptr = (uint8_t*)cnf->interface_defaults; /*save interface specific lqmults, as they are merged togehter later*/ mult_orig = io->lq_mult; assert(in->cnf); assert(in->cnfi); for (pos = 0; pos < sizeof(*in->cnf); pos++) { if (cnfptr[pos] != cnfiptr[pos]) { cnfptr[pos] = defptr[pos]; cnfiptr[pos]=0x00; } else cnfiptr[pos]=0xFF; } io->lq_mult=NULL; /*copy default lqmults into this interface*/ for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) { /*search same lqmult in orig_list*/ for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) { if (ipequal(&mult_orig_walk->addr,&mult->addr)) { break; } } if (mult_orig_walk == NULL) { mult_temp=malloc(sizeof(struct olsr_lq_mult)); memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult)); mult_temp->next=io->lq_mult; io->lq_mult=mult_temp; } } } if (in->name == NULL || !strlen(in->name)) { fprintf(stderr, "Interface has no name!\n"); return -1; } if (io == NULL) { fprintf(stderr, "Interface %s has no configuration!\n", in->name); return -1; } /*merge lqmults*/ if (mult_orig!=NULL) { io->orig_lq_mult_cnt=1; /*search last of interface specific lqmults*/ mult = mult_orig; while (mult->next!=NULL) { mult=mult->next; } /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/ mult->next=io->lq_mult; io->lq_mult=mult_orig; } if (olsrd_sanity_check_interface_cnf(io, cnf, in->name)) return -1; in = in->next; } return 0; }
void olsrd_print_cnf(struct olsrd_config *cnf) { struct ip_prefix_list *h = cnf->hna_entries; struct olsr_if *in = cnf->interfaces; struct plugin_entry *pe = cnf->plugins; struct ip_prefix_list *ie = cnf->ipc_nets; printf(" *** olsrd configuration ***\n"); printf("Debug Level : %d\n", cnf->debug_level); if (cnf->ip_version == AF_INET6) printf("IpVersion : 6\n"); else printf("IpVersion : 4\n"); if (cnf->allow_no_interfaces) printf("No interfaces : ALLOWED\n"); else printf("No interfaces : NOT ALLOWED\n"); printf("TOS : 0x%02x\n", cnf->tos); printf("OlsrPort : 0x%03x\n", cnf->olsrport); printf("RtTable : %u\n", cnf->rt_table); printf("RtTableDefault : %u\n", cnf->rt_table_default); printf("RtTableTunnel : %u\n", cnf->rt_table_tunnel); if (cnf->willingness_auto) printf("Willingness : AUTO\n"); else printf("Willingness : %d\n", cnf->willingness); printf("IPC connections : %d\n", cnf->ipc_connections); while (ie) { struct ipaddr_str strbuf; if (ie->net.prefix_len == olsr_cnf->maxplen) { printf("\tHost %s\n", olsr_ip_to_string(&strbuf, &ie->net.prefix)); } else { printf("\tNet %s/%d\n", olsr_ip_to_string(&strbuf, &ie->net.prefix), ie->net.prefix_len); } ie = ie->next; } printf("Pollrate : %0.2f\n", cnf->pollrate); printf("NIC ChangPollrate: %0.2f\n", cnf->nic_chgs_pollrate); printf("TC redundancy : %d\n", cnf->tc_redundancy); printf("MPR coverage : %d\n", cnf->mpr_coverage); printf("LQ level : %d\n", cnf->lq_level); printf("LQ fish eye : %d\n", cnf->lq_fish); printf("LQ aging factor : %f\n", cnf->lq_aging); printf("LQ algorithm name: %s\n", cnf->lq_algorithm ? cnf->lq_algorithm : "default"); printf("NAT threshold : %f\n", cnf->lq_nat_thresh); printf("Clear screen : %s\n", cnf->clear_screen ? "yes" : "no"); printf("Use niit : %s\n", cnf->use_niit ? "yes" : "no"); printf("Smart Gateway : %s\n", cnf->smart_gw_active ? "yes" : "no"); printf("SmGw. Allow NAT : %s\n", cnf->smart_gw_allow_nat ? "yes" : "no"); printf("Smart Gw. Uplink : %s\n", GW_UPLINK_TXT[cnf->smart_gw_type]); printf("SmGw. Uplink NAT : %s\n", cnf->smart_gw_uplink_nat ? "yes" : "no"); printf("Smart Gw. speed : %d kbit/s up, %d kbit/s down\n", cnf->smart_gw_uplink, cnf->smart_gw_downlink); if (olsr_cnf->smart_gw_prefix.prefix_len == 0) { printf("# Smart Gw. prefix : ::/0\n"); } else { printf("Smart Gw. prefix : %s\n", olsr_ip_prefix_to_string(&cnf->smart_gw_prefix)); } /* Interfaces */ if (in) { /*print interface default config*/ printf(" InterfaceDefaults: \n"); olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, true); while (in) { if (cnf->interface_defaults!=in->cnf) { printf(" dev: \"%s\"\n", in->name); olsrd_print_interface_cnf(in->cnf, in->cnfi, false); } in = in->next; } } /* Plugins */ if (pe) { printf("Plugins:\n"); while (pe) { printf("\tName: \"%s\"\n", pe->name); pe = pe->next; } } /* Hysteresis */ if (cnf->use_hysteresis) { printf("Using hysteresis:\n"); printf("\tScaling : %0.2f\n", cnf->hysteresis_param.scaling); printf("\tThr high/low : %0.2f/%0.2f\n", cnf->hysteresis_param.thr_high, cnf->hysteresis_param.thr_low); } else { printf("Not using hysteresis\n"); } /* HNA IPv4 and IPv6 */ if (h) { printf("HNA%d entries:\n", cnf->ip_version == AF_INET ? 4 : 6); while (h) { struct ipaddr_str buf; printf("\t%s/", olsr_ip_to_string(&buf, &h->net.prefix)); if (cnf->ip_version == AF_INET) { union olsr_ip_addr ip; olsr_prefix_to_netmask(&ip, h->net.prefix_len); printf("%s\n", olsr_ip_to_string(&buf, &ip)); } else { printf("%d\n", h->net.prefix_len); } h = h->next; } } }
int olsrd_sanity_check_cnf(struct olsrd_config *cnf) { struct olsr_if *in = cnf->interfaces; struct if_config_options *io; /* Debug level */ if (cnf->debug_level < MIN_DEBUGLVL || cnf->debug_level > MAX_DEBUGLVL) { fprintf(stderr, "Debuglevel %d is not allowed\n", cnf->debug_level); return -1; } /* IP version */ if (cnf->ip_version != AF_INET && cnf->ip_version != AF_INET6) { fprintf(stderr, "Ipversion %d not allowed!\n", cnf->ip_version); return -1; } /* TOS range */ if (cnf->tos > MAX_TOS) { fprintf(stderr, "TOS %d is not allowed\n", cnf->tos); return -1; } /* TOS ECN */ if (cnf->tos & 0x03) { fprintf(stderr, "TOS %d has set ECN bits, not allowed\n", cnf->tos); return -1; } if (cnf->willingness_auto == false && (cnf->willingness > MAX_WILLINGNESS)) { fprintf(stderr, "Willingness %d is not allowed\n", cnf->willingness); return -1; } /* Hysteresis */ if (cnf->use_hysteresis == true) { if (cnf->hysteresis_param.scaling < (float)MIN_HYST_PARAM || cnf->hysteresis_param.scaling > (float)MAX_HYST_PARAM) { fprintf(stderr, "Hyst scaling %0.2f is not allowed\n", (double)cnf->hysteresis_param.scaling); return -1; } if (cnf->hysteresis_param.thr_high <= cnf->hysteresis_param.thr_low) { fprintf(stderr, "Hyst upper(%0.2f) thr must be bigger than lower(%0.2f) threshold!\n", (double)cnf->hysteresis_param.thr_high, (double)cnf->hysteresis_param.thr_low); return -1; } if (cnf->hysteresis_param.thr_high < (float)MIN_HYST_PARAM || cnf->hysteresis_param.thr_high > (float)MAX_HYST_PARAM) { fprintf(stderr, "Hyst upper thr %0.2f is not allowed\n", (double)cnf->hysteresis_param.thr_high); return -1; } if (cnf->hysteresis_param.thr_low < (float)MIN_HYST_PARAM || cnf->hysteresis_param.thr_low > (float)MAX_HYST_PARAM) { fprintf(stderr, "Hyst lower thr %0.2f is not allowed\n", (double)cnf->hysteresis_param.thr_low); return -1; } } /* Pollrate */ if (cnf->pollrate < (float)MIN_POLLRATE || cnf->pollrate > (float)MAX_POLLRATE) { fprintf(stderr, "Pollrate %0.2f is not allowed\n", (double)cnf->pollrate); return -1; } /* NIC Changes Pollrate */ if (cnf->nic_chgs_pollrate < (float)MIN_NICCHGPOLLRT || cnf->nic_chgs_pollrate > (float)MAX_NICCHGPOLLRT) { fprintf(stderr, "NIC Changes Pollrate %0.2f is not allowed\n", (double)cnf->nic_chgs_pollrate); return -1; } /* TC redundancy */ if (cnf->tc_redundancy != 2) { fprintf(stderr, "Sorry, tc-redundancy 0/1 are not working on 0.5.6. " "It was discovered late in the stable tree development and cannot " "be solved without a difficult change in the dijkstra code. " "Feel free to contact the olsr-user mailinglist " "(http://www.olsr.org/?q=mailing-lists) to learn more " "about the problem. The next version of OLSR will have working " "tc-redundancy again.\n"); return -1; } /* MPR coverage */ if (cnf->mpr_coverage < MIN_MPR_COVERAGE || cnf->mpr_coverage > MAX_MPR_COVERAGE) { fprintf(stderr, "MPR coverage %d is not allowed\n", cnf->mpr_coverage); return -1; } /* Link Q and hysteresis cannot be activated at the same time */ if (cnf->use_hysteresis == true && cnf->lq_level) { fprintf(stderr, "Hysteresis and LinkQuality cannot both be active! Deactivate one of them.\n"); return -1; } /* Link quality level */ if (cnf->lq_level != 0 && cnf->lq_level != 2) { fprintf(stderr, "LQ level %d is not allowed\n", cnf->lq_level); return -1; } /* Link quality window size */ if (cnf->lq_level && (cnf->lq_aging < (float)MIN_LQ_AGING || cnf->lq_aging > (float)MAX_LQ_AGING)) { fprintf(stderr, "LQ aging factor %f is not allowed\n", (double)cnf->lq_aging); return -1; } /* NAT threshold value */ if (cnf->lq_level && (cnf->lq_nat_thresh < 0.1f || cnf->lq_nat_thresh > 1.0f)) { fprintf(stderr, "NAT threshold %f is not allowed\n", (double)cnf->lq_nat_thresh); return -1; } #ifdef __linux__ #if !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION #error "Both LINUX_VERSION_CODE and KERNEL_VERSION need to be defined" #else /* !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) if (cnf->ip_version == AF_INET6 && cnf->smart_gw_active) { fprintf(stderr, "Smart gateways are not supported for linux kernel < 2.6.24 and ipv6\n"); return -1; } #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */ #endif /* !defined LINUX_VERSION_CODE || !defined KERNEL_VERSION */ /* this rtpolicy settings are also currently only used in Linux */ if (olsrd_sanity_check_rtpolicy(cnf)) { return -1; } #endif /* __linux__ */ if (in == NULL) { fprintf(stderr, "No interfaces configured!\n"); return -1; } if (cnf->min_tc_vtime < 0.0f) { fprintf(stderr, "Error, negative minimal tc time not allowed.\n"); return -1; } if (cnf->min_tc_vtime > 0.0f) { fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n"); } #ifdef __linux__ if ((cnf->smart_gw_use_count < MIN_SMARTGW_USE_COUNT_MIN) || (cnf->smart_gw_use_count > MAX_SMARTGW_USE_COUNT_MAX)) { fprintf(stderr, "Error, bad gateway use count %d, outside of range [%d, %d]\n", cnf->smart_gw_use_count, MIN_SMARTGW_USE_COUNT_MIN, MAX_SMARTGW_USE_COUNT_MAX); return -1; } if (cnf->smart_gw_use_count > 1) { struct sgw_egress_if * sgwegressif = cnf->smart_gw_egress_interfaces; if (!cnf->smart_gw_policyrouting_script) { fprintf(stderr, "Error, no policy routing script configured in multi-gateway mode\n"); return -1; } { struct stat statbuf; int r = stat(cnf->smart_gw_policyrouting_script, &statbuf); if (r) { fprintf(stderr, "Error, policy routing script not found: %s\n", strerror(errno)); return -1; } if (!S_ISREG(statbuf.st_mode)) { fprintf(stderr, "Error, policy routing script not a regular file\n"); return -1; } if (statbuf.st_uid) { fprintf(stderr, "Error, policy routing script must be owned by root\n"); return -1; } if (!(statbuf.st_mode & (S_IRUSR | S_IXUSR))) { fprintf(stderr, "Error, policy routing script is not executable\n"); return -1; } } /* egress interface(s) must be set */ if (!sgwegressif) { fprintf(stderr, "Error, no egress interfaces configured in multi-gateway mode\n"); return -1; } /* an egress interface must not be an OLSR interface */ while (sgwegressif) { struct olsr_if * olsrif = cnf->interfaces; while (olsrif) { if (!strcmp(olsrif->name, sgwegressif->name)) { fprintf(stderr, "Error, egress interface %s already is an OLSR interface\n", sgwegressif->name); return -1; } olsrif = olsrif->next; } cnf->smart_gw_egress_interfaces_count++; sgwegressif = sgwegressif->next; } if (cnf->smart_gw_egress_interfaces_count > MAX_SMARTGW_EGRESS_INTERFACE_COUNT_MAX) { fprintf(stderr, "Error, egress interface count %u not in range [1, %u]\n", cnf->smart_gw_egress_interfaces_count, MAX_SMARTGW_EGRESS_INTERFACE_COUNT_MAX); return -1; } { uint8_t egressLow = cnf->smart_gw_mark_offset_egress; uint8_t egressHigh = egressLow + cnf->smart_gw_egress_interfaces_count - 1; uint8_t tunnelsLow = cnf->smart_gw_mark_offset_tunnels; uint8_t tunnelsHigh = tunnelsLow + cnf->smart_gw_use_count - 1; bool overlap = false; /* check that the egress interface marks range does not overflow */ if (egressLow > (UINT8_MAX - cnf->smart_gw_egress_interfaces_count)) { fprintf(stderr, "Error, egress interface mark offset %u together with egress interface count %u overflows range [0, %u]\n", egressLow, cnf->smart_gw_egress_interfaces_count, UINT8_MAX); return -1; } /* check that the tunnel interface marks range does not overflow */ if (tunnelsLow > (UINT8_MAX - cnf->smart_gw_use_count)) { fprintf(stderr, "Error, tunnel interface mark offset %u together with use count %u overflows range [0, %u]\n", tunnelsLow, cnf->smart_gw_use_count, UINT8_MAX); return -1; } /* check that the egress and tunnel marks ranges do not overlap */ overlap = ((tunnelsLow <= egressLow) && (egressLow <= tunnelsHigh)); overlap = overlap || ((tunnelsLow <= egressHigh) && (egressHigh <= tunnelsHigh)); overlap = overlap || ((egressLow <= tunnelsLow) && (tunnelsLow <= egressHigh)); overlap = overlap || ((egressLow <= tunnelsHigh) && (tunnelsHigh <= egressHigh)); if (overlap) { fprintf(stderr, "Error, egress interface mark range [%u, %u] overlaps with tunnel interface mark range [%u, %u]\n", egressLow, egressHigh, tunnelsLow, tunnelsHigh); return -1; } } } if (cnf->smart_gw_period < MIN_SMARTGW_PERIOD || cnf->smart_gw_period > MAX_SMARTGW_PERIOD) { fprintf(stderr, "Error, bad gateway period: %d msec (should be %d-%d)\n", cnf->smart_gw_period, MIN_SMARTGW_PERIOD, MAX_SMARTGW_PERIOD); return -1; } if (cnf->smart_gw_stablecount < MIN_SMARTGW_STABLE || cnf->smart_gw_stablecount > MAX_SMARTGW_STABLE) { fprintf(stderr, "Error, bad gateway stable count: %d (should be %d-%d)\n", cnf->smart_gw_stablecount, MIN_SMARTGW_STABLE, MAX_SMARTGW_STABLE); return -1; } if (((cnf->smart_gw_thresh < MIN_SMARTGW_THRES) || (cnf->smart_gw_thresh > MAX_SMARTGW_THRES)) && (cnf->smart_gw_thresh != 0)) { fprintf(stderr, "Smart gateway threshold %d is not allowed (should be %d-%d)\n", cnf->smart_gw_thresh, MIN_SMARTGW_THRES, MAX_SMARTGW_THRES); return -1; } /* no checks are needed on: * - cnf->smart_gw_weight_exitlink_up * - cnf->smart_gw_weight_exitlink_down * - cnf->smart_gw_weight_etx * - cnf->smart_gw_divider_etx */ if (cnf->smart_gw_type >= GW_UPLINK_CNT) { fprintf(stderr, "Error, illegal gateway uplink type: %d\n", cnf->smart_gw_type); return -1; } if (cnf->smart_gw_downlink < MIN_SMARTGW_SPEED || cnf->smart_gw_downlink > MAX_SMARTGW_SPEED) { fprintf(stderr, "Error, bad gateway downlink speed: %d kbit/s (should be %d-%d)\n", cnf->smart_gw_downlink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED); return -1; } if (cnf->smart_gw_uplink < MIN_SMARTGW_SPEED || cnf->smart_gw_uplink > MAX_SMARTGW_SPEED) { fprintf(stderr, "Error, bad gateway uplink speed: %d kbit/s (should be %d-%d)\n", cnf->smart_gw_uplink, MIN_SMARTGW_SPEED, MAX_SMARTGW_SPEED); return -1; } #endif /* __linux__ */ if (cnf->interface_defaults == NULL) { /* get a default configuration if the user did not specify one */ cnf->interface_defaults = get_default_if_config(); } else { olsrd_print_interface_cnf(cnf->interface_defaults, cnf->interface_defaults, false); olsrd_sanity_check_interface_cnf(cnf->interface_defaults, cnf, interface_defaults_name); } /* Interfaces */ while (in) { struct olsr_lq_mult *mult, *mult_orig; assert(in->cnf); assert(in->cnfi); io = in->cnf; olsrd_print_interface_cnf(in->cnf, in->cnfi, false); /*apply defaults*/ { size_t pos; struct olsr_lq_mult *mult_temp, *mult_orig_walk; uint8_t *cnfptr = (uint8_t*)in->cnf; uint8_t *cnfiptr = (uint8_t*)in->cnfi; uint8_t *defptr = (uint8_t*)cnf->interface_defaults; /*save interface specific lqmults, as they are merged togehter later*/ mult_orig = io->lq_mult; for (pos = 0; pos < sizeof(*in->cnf); pos++) { if (cnfptr[pos] != cnfiptr[pos]) { cnfptr[pos] = defptr[pos]; cnfiptr[pos]=0x00; } else cnfiptr[pos]=0xFF; } io->lq_mult=NULL; /*copy default lqmults into this interface*/ for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) { /*search same lqmult in orig_list*/ for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) { if (ipequal(&mult_orig_walk->addr,&mult->addr)) { break; } } if (mult_orig_walk == NULL) { mult_temp=malloc(sizeof(struct olsr_lq_mult)); memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult)); mult_temp->next=io->lq_mult; io->lq_mult=mult_temp; } } } if (in->name == NULL || !strlen(in->name)) { fprintf(stderr, "Interface has no name!\n"); return -1; } if (io == NULL) { fprintf(stderr, "Interface %s has no configuration!\n", in->name); return -1; } /*merge lqmults*/ if (mult_orig!=NULL) { io->orig_lq_mult_cnt=1; /*search last of interface specific lqmults*/ mult = mult_orig; while (mult->next!=NULL) { mult=mult->next; } /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/ mult->next=io->lq_mult; io->lq_mult=mult_orig; } if (olsrd_sanity_check_interface_cnf(io, cnf, in->name)) return -1; in = in->next; } return 0; }