int set_tun_default_route_v6() { /* * Assign route to ::/1 and 8000::/1 via tun interface */ lisp_addr_t dest; lisp_addr_t *src = NULL; uint32_t prefix_len = 0; uint32_t metric = 0; prefix_len = 1; metric = 512; if (router_mode == TRUE){ if (default_out_iface_v6 != NULL){ src = default_out_iface_v6->ipv6_address; } } get_lisp_addr_from_char("::",&dest); if (add_route(AF_INET6, tun_ifindex, &dest, src, NULL, prefix_len, metric, RT_TABLE_MAIN) != GOOD){ return (BAD); } get_lisp_addr_from_char("8000::",&dest); if (add_route(AF_INET6, tun_ifindex, &dest, src, NULL, prefix_len, metric, RT_TABLE_MAIN) != GOOD){ return (BAD); } return(GOOD); }
int set_tun_default_route_v6() { /* * Assign route to ::/1 and 8000::/1 via tun interface */ lisp_addr_t dest; lisp_addr_t *src = NULL; lisp_addr_t gw; uint32_t prefix_len = 0; uint32_t metric = 0; prefix_len = 1; metric = 512; get_lisp_addr_from_char("::",&gw); #ifdef ROUTER if (default_out_iface_v6 != NULL){ src = default_out_iface_v6->ipv6_address; } #endif get_lisp_addr_from_char("::",&dest); add_route(AF_INET6, tun_ifindex, &dest, src, NULL, prefix_len, metric, RT_TABLE_MAIN); get_lisp_addr_from_char("8000::",&dest); add_route(AF_INET6, tun_ifindex, &dest, src, NULL, prefix_len, metric, RT_TABLE_MAIN); return(GOOD); }
void process_new_gateway ( lisp_addr_t gateway, lispd_iface_elt *iface ) { lisp_addr_t **gw_addr = NULL; int afi = AF_UNSPEC; switch(gateway.afi) { case AF_INET: gw_addr = &(iface->ipv4_gateway); afi = AF_INET; break; case AF_INET6: gw_addr = &(iface->ipv6_gateway); afi = AF_INET6; break; default: return; } if (*gw_addr == NULL) { // The default gateway of this interface is not deffined yet *gw_addr = clone_lisp_addr(&gateway); if (*gw_addr == NULL) { free (*gw_addr); *gw_addr = NULL; return; } } else { copy_lisp_addr(*gw_addr,&gateway); } add_route(afi,iface->iface_index,NULL,NULL,*gw_addr,0,100,iface->iface_index); }
int main(void) { struct mg_server *server; //Start network configurations //setup_ap(); //setup_dhcp(); //setup_iptables(); // Create and configure the server server = mg_create_server(NULL, ev_handler); mg_set_option(server, "document_root", "."); mg_set_option(server, "listening_port", "8080"); limparRotas(); init_resources_table(); criar_tabela(); //registra a rota do log do cliente add_route("/login", handle_post_request); // Serve request. Hit Ctrl-C to terminate the program printf("Starting on port %s\n", mg_get_option(server, "listening_port")); for (;;) { mg_poll_server(server, 1000); } // Cleanup, and free server instance mg_destroy_server(&server); return 0; }
/* * Delete/retain addresses to list and handle the route entries. */ void install_address(struct preflist **plist, struct interface *ifp) { struct preflist *pl, **ppl, *temp; /* DELETE FIRST */ for (pl = *plist, ppl = plist; pl;) { temp = pl; pl = pl->pl_next; if (temp->pl_flag != PL_DELADDR) { ppl = &(temp->pl_next); continue; } else { *ppl = pl; del_route(temp, ifp); free(temp); } } /* AND THEN ADD */ for (pl = *plist, ppl = plist; pl;) { temp = pl; pl = pl->pl_next; if (temp->pl_flag == PL_NEWADDR) { if (ifp->if_flag & IFF_UP && ifp->if_lladdr != NULL) add_route(temp, ifp); } ppl = &(temp->pl_next); } return; }
int main(void) { //firewall char * ipfw_command2[] = {"add","set", "3", "allow", "all", "from", "192.168.2.100", "to", "192.168.1.100"}; char * ipfw_command1[] = {"add","set", "2", "allow", "all", "from", "192.168.1.100", "to", "192.168.2.100"}; //char * ipfw_nat_config1[] = {"nat-config", "1", "ip", "192.168.1.1", "redirect_addr", "192.168.2.100", "192.168.5.1"}; //char * ipfw_nat_config2[] = {"nat-config", "2", "if", "eth1", "redirect_addr", "192.168.1.100", "192.168.2.1"}; //char * ipfw_nat1[] = {"add", "nat", "1", "ip", "from", "192.168.2.100", "to","192.168.1.100"}; //char * ipfw_nat2[] = {"add", "nat", "2", "ip", "from", "192.168.2.100", "to","192.168.2.1"}; //vnet_ipfw_init(); //ipfw_nat_init(); //struct cfg_nat cfg; //(*ipfw_nat_cfg_ptr)(&cfg); //ipfw_config_nat(sizeof(ipfw_nat_config2)/sizeof(char*), ipfw_nat_config2); //ipfw_config_nat(sizeof(ipfw_nat_config1)/sizeof(char*), ipfw_nat_config1); //ipfw_add(&ipfw_nat2); //ipfw_add(&ipfw_nat1); //ipfw_add(&ipfw_command1); //ipfw_add(&ipfw_command2); init_all_network_interfaces(); //routing cyg_route_init(); cyg_route_reinit(); //example - transfers packets from 192.168.5.0/24 to 192.168.2.100 via eth0 //add_route("eth0", "192.168.5.1", "255.255.255.0", "192.168.2.100"); //mandatory for proper routing, do not remove add_route("eth0", "192.168.2.100", "255.255.255.0", "192.168.2.100"); add_route("eth1", "192.168.1.100", "255.255.255.0", "192.168.1.100"); show_network_tables(printf); printf("Hello, eCos world!\n"); while (1) { printf("Sleeping\n"); cyg_thread_delay(1000); } return 0; }
void configure_routing(void) { int i; #if IN_COOJA node_rank = node_id; #else node_rank = -1; for(i=0; i<(sizeof(motes_addrs)/sizeof(struct id_to_addrs)); ++i) { if(node_id == motes_addrs[i].id) { node_rank = i+1; break; } } if(node_rank == -1) { printf("unable to configure routing, node_id=%d\n", node_id); return; } #endif printf("configure_routing, node_id=%d, node_rank %d\n", node_id, node_rank); if (node_rank == 1) { /* border router #1 */ add_route_ext(2, 2); for(i=2; i<=NODES_IN_MAP; ++i) { add_route(i, 2); } } else if (node_rank < NODES_IN_MAP) { /* other node */ add_route_ext(1, node_rank-1); add_route_ext(2, node_rank+1); for(i=1; i<=NODES_IN_MAP; ++i) { if(i<node_rank) { add_route(i, node_rank-1); } else if(i>node_rank) { add_route(i, node_rank+1); } } } else if (node_rank == NODES_IN_MAP) { /* 2nd border router */ add_route_ext(1, NODES_IN_MAP-1); for(i=1; i<=NODES_IN_MAP-1; ++i) { add_route(i, NODES_IN_MAP-1); } } }
void Sip_Request::add_routes(const std::list<Sip_Uri> &routes) { std::list<Sip_Uri>::const_reverse_iterator i; std::list<Sip_Uri>::const_reverse_iterator first = routes.rend(); for( i = routes.rbegin(); i != first; ++i ) { const Sip_Uri &route = *i; add_route( route.get_string() ); } }
/*! Adds the default routes that every interface address needs, ie. the local host route, and one for the subnet (if set). */ void InterfaceAddress::AddDefaultRoutes(int32 option) { net_route route; route.destination = local; route.gateway = NULL; route.interface_address = this; if (mask != NULL && (option == SIOCSIFNETMASK || option == SIOCSIFADDR)) { route.mask = mask; route.flags = 0; add_route(domain, &route); } if (option == SIOCSIFADDR) { route.mask = NULL; route.flags = RTF_LOCAL | RTF_HOST; add_route(domain, &route); } }
int set_tun_default_route_v4() { /* * Assign route to 0.0.0.0/1 and 128.0.0.0/1 via tun interface */ lisp_addr_t dest; uint32_t prefix_len = 0; uint32_t metric = 0; prefix_len = 1; metric = 0; get_lisp_addr_from_char("0.0.0.0",&dest); if (add_route(AF_INET, tun_ifindex, &dest, NULL, NULL, prefix_len, metric, RT_TABLE_MAIN) != GOOD){ return (BAD); } get_lisp_addr_from_char("128.0.0.0",&dest); if (add_route(AF_INET, tun_ifindex, &dest, NULL, NULL, prefix_len, metric, RT_TABLE_MAIN)!=GOOD){ return (BAD); } return(GOOD); }
void DjVuPortcaster::copy_routes(DjVuPort * dst, const DjVuPort * src) // For every route src->x or x->src, it creates a new one: // dst->x or x->dst respectively. It's useful when you create a copy // of a port and you want the copy to stay connected. { GCriticalSectionLock lock(&map_lock); if (!cont_map.contains(src) || src->get_count()<=0 || !cont_map.contains(dst) || dst->get_count()<=0) return; for(GPosition pos=route_map;pos;++pos) { GList<void *> & list=*(GList<void *> *) route_map[pos]; if (route_map.key(pos) == src) for(GPosition pos=list;pos;++pos) add_route(dst, (DjVuPort *) list[pos]); for(GPosition pos=list;pos;++pos) if ((DjVuPort*)(list[pos]) == src) add_route((DjVuPort *) route_map.key(pos), dst); } }
static void build_ra(struct safe_buffer * sb, struct Interface const * iface) { add_ra_header(sb, &iface->ra_header_info, iface->state_info.cease_adv); if (iface->AdvPrefixList) { add_prefix(sb, iface->AdvPrefixList, iface->state_info.cease_adv); } if (iface->AdvRouteList) { add_route(sb, iface->AdvRouteList, iface->state_info.cease_adv); } if (iface->AdvRDNSSList) { add_rdnss(sb, iface->AdvRDNSSList, iface->state_info.cease_adv); } if (iface->AdvDNSSLList) { add_dnssl(sb, iface->AdvDNSSLList, iface->state_info.cease_adv); } if (iface->AdvPvdList) { add_pvd(sb, iface->AdvPvdList, iface->state_info.cease_adv); } if (iface->AdvLinkMTU != 0) { add_mtu(sb, iface->AdvLinkMTU); } if (iface->AdvSourceLLAddress && iface->sllao.if_hwaddr_len > 0) { add_sllao(sb, &iface->sllao); } if (iface->mipv6.AdvIntervalOpt) { add_mipv6_rtr_adv_interval(sb, iface->MaxRtrAdvInterval); } if (iface->mipv6.AdvHomeAgentInfo && (iface->mipv6.AdvMobRtrSupportFlag || iface->mipv6.HomeAgentPreference != 0 || iface->mipv6.HomeAgentLifetime != iface->ra_header_info.AdvDefaultLifetime)) { add_mipv6_home_agent_info(sb, &iface->mipv6); } if (iface->AdvLowpanCoList) { add_lowpanco(sb, iface->AdvLowpanCoList); } if (iface->AdvAbroList) { add_abro(sb, iface->AdvAbroList); } }
status_t control_routes(struct net_interface* _interface, net_domain* domain, int32 option, void* argument, size_t length) { TRACE("control_routes(interface %p, domain %p, option %" B_PRId32 ")\n", _interface, domain, option); Interface* interface = (Interface*)_interface; switch (option) { case SIOCADDRT: case SIOCDELRT: { // add or remove a route if (length != sizeof(struct ifreq)) return B_BAD_VALUE; route_entry entry; if (user_memcpy(&entry, &((ifreq*)argument)->ifr_route, sizeof(route_entry)) != B_OK) return B_BAD_ADDRESS; net_route_private route; status_t status; if ((status = user_copy_address(entry.destination, &route.destination)) != B_OK || (status = user_copy_address(entry.mask, &route.mask)) != B_OK || (status = user_copy_address(entry.gateway, &route.gateway)) != B_OK) return status; InterfaceAddress* address = interface->FirstForFamily(domain->family); route.mtu = entry.mtu; route.flags = entry.flags; route.interface_address = address; if (option == SIOCADDRT) status = add_route(domain, &route); else status = remove_route(domain, &route); if (address != NULL) address->ReleaseReference(); return status; } } return B_BAD_VALUE; }
int add_share_route(PACKET pkt) { int iface; ip_addr nexthop; RTMIB rt; struct ip * pip; NET ifp; pip = (struct ip * )pkt->nb_prot; rt = rt_lookup(pip->ip_src); ifp = pkt->net; /* net we received packet on */ iface = if_netnumber(ifp); /* We need net index too.... */ /* if we already have a route, just patch the net & return. */ if(rt && (rt->ipRouteDest == pip->ip_src)) { rt->ifp = ifp; return 0; } /* Figure out what to use for a "next hop". If it appears * to be a local IP address, then use the IP address of the * sender; else if there is a route get the GW from that, else if * the iface has one use that. As a last resort, fall back to using * the sender's address as a next hop. */ if((ifp->n_ipaddr & ifp->snmask) == (pip->ip_src & ifp->snmask)) { nexthop = pip->ip_src; } else if(rt) nexthop = rt->ipRouteNextHop; else if(pkt->net->n_defgw) nexthop = ifp->n_defgw; else nexthop = pip->ip_src; /* Now make an explicit route back to the sender */ rt = add_route(pip->ip_src, 0xFFFFFFFF, nexthop, iface, IPRP_OTHER); if(rt) return 0; else return ENP_RESOURCE; }
int parse_input(FILE* stream, struct city** cities, size_t maxcount) { size_t i = 0; while (i < maxcount && !feof(stream)) { char from[16], to[16]; unsigned distance; struct city* fromcity, * tocity; int parse_status = fscanf(stream, "%15s to %15s = %u\n", from, to, &distance); if (parse_status != 3) { char garbage[21]; if (ferror(stream)) perror("can't read input"); else { fgets(garbage, 20, stream); fprintf(stderr, "parse error near '%s'\n", garbage); } return 0; } fromcity = find_or_add_city(cities, from, maxcount); if (!fromcity) { fprintf(stderr, "could not add city '%s'\n", from); return 0; } tocity = find_or_add_city(cities, to, maxcount); if (!tocity) { fprintf(stderr, "could not add city '%s'\n", to); return 0; } add_route(fromcity, tocity, distance); } return 1; }
int get_route_table_by_snmp(struct route_table *rt) { ipRouteTable *rtable = NULL ; // getIpRouteTable(rt->routerip, &rtable); getIpForwardTable(rt->routerip, &rtable); if(rtable == NULL) { printf("Get routing table failed\n"); return NULL; } ipRouteTable* r = rtable->next; int total = 0; while(r!=NULL){ struct route* newroute = malloc_z(struct route); inet_pton(AF_INET, r->ipRouteDest ,&newroute->prefix.prefix); newroute->prefix.family = AF_INET; newroute->prefix.prefixlen = get_prefix_length(r->ipRouteMask); inet_pton(AF_INET, r->ipRouteNextHop, &newroute->gateway); newroute->interface_id = atoi(r->ipRouteIfIndex); newroute->metric = atoi(r->ipRouteMetric); if ( strcmp(r->ipRouteType,"local") == 0 ) newroute->type = ROUTE_TYPE_LOCAL; else newroute->type = ROUTE_TYPE_REMOTE; newroute->dirty = FRESH_STATUS; struct route** rr = find_before_route(rt->routes, *newroute); if( rr== NULL) add_route(rt->routes, newroute); else update_route(rr, newroute); total++; r = r->next; } freeIpRouteTable(rtable); rt->route_table_len = total; }
void Sip_Request::add_route(const std::string &addr, int32_t port, const std::string &transport) { std::string u = "<sip:" + addr; if( port ) { char buf[20]; sprintf(buf, "%d", port); u = u + ":" + buf; } if( transport != "" ) { u = u + ";transport=" + transport; } u = u + ";lr>"; add_route( u ); }
void netlink_link_down(struct rproto *netlink, struct link *link) { /* Must find all routes, that depend on this link.. and call unlearn */ struct route *r, *q; struct rtable *tmp; tmp = new_rtable(); for (r=main_rtable->routes; r ; r=r->next) { if (r->source_link != link) continue; if (r->flags & RF_UNREACH) continue; q = dup_route(r); q->flags |= RF_UNREACH; q->garbage = time(NULL) + 120; add_route(tmp, q); } if(tmp->num_routes != 0) unlearn_routes(&system_proto, tmp); free_rtable(tmp); }
void netlink_link_up(struct rproto *netlink, struct link *link) { struct rtable *tmp; struct route *route; if(!(link->flags & LF_UP)) return; if(!(link->flags & LF_ANNOUNCETHIS)) return; if((route = malloc(sizeof(struct route))) == NULL) { error("Insufficient memory allocating route"); return; } tmp = new_rtable(); if(link->flags & LF_POINTOPOINT) { route->dst = link->broadcast & link->netmask; }else{ route->dst = link->address & link->netmask; } route->dstmask = link->netmask; route->nexthop = 0; // Через нас route->metric = link->cost; route->type = RT_DYNAMIC; route->flags = 0; route->source = 0; route->source_link = link; route->domain = 0; route->expire = 0; route->garbage = 0; route->timerset = 0; strncpy(route->iface,link->iface,sizeof(route->iface)); add_route(tmp, route); learn_routes(&system_proto, tmp); free_rtable(tmp); }
JNIEXPORT void JNICALL Java_ch_unibas_ccn_1lite_1android_CcnLiteAndroid_relayRX(JNIEnv* env, jobject thiz, jbyteArray addr, jbyteArray data) { int len; unsigned char buf[1024]; sockunion su; len = (*env)->GetArrayLength(env, data); DEBUGMSG(DEBUG, "relayRX: %d bytes\n", len); memset(&su, 0, sizeof(su)); su.linklayer.sll_family = AF_PACKET; (*env)->GetByteArrayRegion(env, addr, 0, ETH_ALEN, (signed char*) &su.linklayer.sll_addr); if (len > sizeof(buf)) len = sizeof(buf); (*env)->GetByteArrayRegion(env, data, 0, len, (signed char*) buf); ccnl_core_RX(&theRelay, 0, buf, len, (struct sockaddr*) &su, sizeof(su)); // hack: when the first packet from the BT LE device is received, // (and the FIB is empty), install two forwarding entries if (theRelay.faces && (!theRelay.fib || theRelay.fib->tap)) { theRelay.faces->flags |= CCNL_FACE_FLAGS_STATIC; #ifdef USE_SUITE_CCNTLV add_route("/TinC", theRelay.faces, CCNL_SUITE_CCNTLV, 20); add_route("/TinF", theRelay.faces, CCNL_SUITE_CCNTLV, 20); #endif #ifdef USE_SUITE_NDNTLV add_route("/TinC", theRelay.faces, CCNL_SUITE_IOTTLV, 20); add_route("/TinF", theRelay.faces, CCNL_SUITE_IOTTLV, 20); #endif #ifdef USE_SUITE_NDNTLV add_route("/TinC", theRelay.faces, CCNL_SUITE_NDNTLV, 20); add_route("/TinF", theRelay.faces, CCNL_SUITE_NDNTLV, 20); #endif return; } }
static switch_status_t load_config(void) { char *cf = "enum.conf"; int inameserver = 0; switch_xml_t cfg, xml = NULL, param, settings, route, routes; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); status = SWITCH_STATUS_FALSE; goto done; } globals.timeout = 5000; globals.retries = 3; globals.random = 0; if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { const char *var = switch_xml_attr_soft(param, "name"); const char *val = switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "default-root")) { set_global_root(val); } else if (!strcasecmp(var, "auto-reload")) { globals.auto_reload = switch_true(val); } else if (!strcasecmp(var, "query-timeout")) { globals.timeout = atoi(val) * 1000; } else if (!strcasecmp(var, "query-timeout-ms")) { globals.timeout = atoi(val); } else if (!strcasecmp(var, "query-timeout-retry")) { globals.retries = atoi(val); } else if (!strcasecmp(var, "random-nameserver")) { globals.random = switch_true(val); } else if (!strcasecmp(var, "default-isn-root")) { set_global_isn_root(val); } else if (!strcasecmp(var, "nameserver") || !strcasecmp(var, "use-server")) { if ( inameserver < ENUM_MAXNAMESERVERS ) { globals.nameserver[inameserver] = (char *) val; inameserver++; } } else if (!strcasecmp(var, "log-level-trace")) { } } } if ((routes = switch_xml_child(cfg, "routes"))) { for (route = switch_xml_child(routes, "route"); route; route = route->next) { char *service = (char *) switch_xml_attr_soft(route, "service"); char *regex = (char *) switch_xml_attr_soft(route, "regex"); char *replace = (char *) switch_xml_attr_soft(route, "replace"); if (service && regex && replace) { add_route(service, regex, replace); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Route!\n"); } } } done: #ifdef _MSC_VER if (!globals.nameserver[0]) { HKEY hKey; DWORD data_sz; char* buf; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_QUERY_VALUE, &hKey); if (hKey) { RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, NULL, &data_sz); if (data_sz) { buf = (char*)malloc(data_sz + 1); RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, (LPBYTE)buf, &data_sz); RegCloseKey(hKey); if(buf[data_sz - 1] != 0) { buf[data_sz] = 0; } switch_replace_char(buf, ' ', 0, SWITCH_FALSE); /* only use the first entry ex "192.168.1.1 192.168.1.2" */ globals.nameserver[0] = buf; } } } #endif if (xml) { switch_xml_free(xml); } if (!globals.root) { set_global_root("e164.org"); } if (!globals.isn_root) { set_global_isn_root("freenum.org"); } return status; }
/** * loads the config data into shared memory (but doesn't really * share it), updates the routing data and writes it to the config * file. Afterwards, the global routing data is reloaded. * * @param opts pointer to the option structure which contains * data to be modified or to be added * * @return 0 on success, -1 on failure */ static int update_route_data(fifo_opt_t * opts) { struct route_data_t * rd; int i,j; int domain_id; str tmp_domain; str tmp_prefix; str tmp_host; str tmp_rewrite_prefix; str tmp_rewrite_suffix; str tmp_comment = str_init(""); if ((rd = shm_malloc(sizeof(struct route_data_t))) == NULL) { SHM_MEM_ERROR; return -1; } memset(rd, 0, sizeof(struct route_data_t)); if (load_config(rd) < 0) { LM_ERR("could not load config"); FIFO_ERR(E_LOADCONF); return -1; } if (rule_fixup(rd) < 0) { LM_ERR("could not fixup rules"); FIFO_ERR(E_RULEFIXUP); return -1; } updated = 0; if (opts->cmd == OPT_ADD) { tmp_domain=opts->domain; tmp_prefix=opts->prefix; tmp_host=opts->host; tmp_rewrite_prefix=opts->rewrite_prefix; tmp_rewrite_suffix=opts->rewrite_suffix; if (tmp_domain.s==NULL) { tmp_domain.s=""; tmp_domain.len=0; } if (tmp_prefix.s==NULL) { tmp_prefix.s=""; tmp_prefix.len=0; } if (tmp_host.s==NULL) { tmp_host.s=""; tmp_host.len=0; } if (tmp_rewrite_prefix.s==NULL) { tmp_rewrite_prefix.s=""; tmp_rewrite_prefix.len=0; } if (tmp_rewrite_suffix.s==NULL) { tmp_rewrite_suffix.s=""; tmp_rewrite_suffix.len=0; } domain_id = map_name2id(rd->domain_map, rd->domain_num, &tmp_domain); if (domain_id < 0) { LM_ERR("cannot find id for domain '%.*s'", tmp_domain.len, tmp_domain.s); goto errout; } if (add_route(rd, 1, domain_id, &tmp_prefix, 0, 0, 0, opts->prob, &tmp_host, opts->strip, &tmp_rewrite_prefix, &tmp_rewrite_suffix, opts->status, opts->hash_index, -1, NULL, &tmp_comment) < 0) { goto errout; } updated = 1; if (rule_fixup(rd) < 0) { LM_ERR("could not fixup rules after route appending"); FIFO_ERR(E_RULEFIXUP); goto errout; } } else { for (i=0; i<rd->carrier_num; i++) { if(rd->carriers[i]){ for (j=0; j<rd->carriers[i]->domain_num; j++) { if (rd->carriers[i]->domains[j] && rd->carriers[i]->domains[j]->tree) { if (update_route_data_recursor(rd->carriers[i]->domains[j]->tree, rd->carriers[i]->domains[j]->name, opts) < 0) { goto errout; } } } } } } if(!updated){ LM_ERR("no match for update found"); FIFO_ERR(E_NOUPDATE); goto errout; } if (save_config(rd) < 0) { LM_ERR("could not save config"); FIFO_ERR(E_SAVECONF); goto errout; } if (reload_route_data() == -1) { LM_ERR("could not reload route data"); FIFO_ERR(E_LOADCONF); goto errout; } clear_route_data(rd); return 0; errout: clear_route_data(rd); return -1; }
device_sound_interface &device_sound_interface::add_route(u32 output, const char *target, double gain, u32 input, u32 mixoutput) { return add_route(output, device().mconfig().current_device(), target, gain, input, mixoutput); }
int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt, unsigned long daddr, unsigned short len, unsigned long saddr, int redo, struct ip_protocol *protocol ) { int size, offset; struct icmp_header *icmph, *icmphr; struct sk_buff *skb; unsigned char *buff; /* drop broadcast packets. */ if ((daddr & 0xff000000) == 0 || (daddr & 0xff000000) == 0xff000000) { skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } buff = skb1->h.raw; icmph = (struct icmp_header *)buff; /* Validate the packet first */ if( icmph->checksum ) { /* Checksums Enabled? */ if( ip_compute_csum( (unsigned char *)icmph, len ) ) { /* Failed checksum! */ PRINTK("\nICMP ECHO failed checksum!"); skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } } print_icmph(icmph); /* Parse the ICMP message */ switch( icmph->type ) { case ICMP_DEST_UNREACH: case ICMP_SOURCE_QUENCH: { struct ip_header *iph; struct ip_protocol *ipprot; unsigned char hash; int err; err = icmph->type << 8 | icmph->code; /* we need to cause the socket to be closed and the error message to be set appropriately. */ iph = (struct ip_header *)(icmph+1); /* get the protocol(s) */ hash = iph->protocol & (MAX_IP_PROTOS -1 ); for (ipprot = ip_protos[hash]; ipprot != NULL; ipprot=ipprot->next) { /* pass it off to everyone who wants it. */ ipprot->err_handler (err, (unsigned char *)iph+4*iph->ihl, iph->daddr, iph->saddr, ipprot); } skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } case ICMP_REDIRECT: { /* we need to put a new route in the routing table. */ struct rtable *rt; /* we will add a new route. */ struct ip_header *iph; iph = (struct ip_header *)(icmph+1); rt = malloc (sizeof (*rt)); if (rt != NULL) { rt->net = iph->daddr; /* assume class C network. Technically this is incorrect, but will give it a try. */ if ((icmph->code & 1) == 0) rt->net &= 0x00ffffff; rt->dev = dev; rt->router = icmph->un.gateway; add_route (rt); } skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } case ICMP_ECHO: /* Allocate an sk_buff response buffer (assume 64 byte IP header) */ size = sizeof( struct sk_buff ) + dev->hard_header_len + 64 + len; skb = malloc( size ); if (skb == NULL) { skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } skb->sk = NULL; skb->mem_addr = skb; skb->mem_len = size; /* Build Layer 2-3 headers for message back to source */ offset = ip_build_header( skb, daddr, saddr, &dev, IP_ICMP, opt, len ); if (offset < 0) { /* Problems building header */ PRINTK("\nCould not build IP Header for ICMP ECHO Response"); free_s (skb->mem_addr, skb->mem_len); skb1->sk = NULL; free_skb (skb1, FREE_READ); return( 0 ); /* just toss the received packet */ } /* Readjust length according to actual IP header size */ skb->len = offset + len; /* Build ICMP_ECHO Response message */ icmphr = (struct icmp_header *)( (char *)( skb + 1 ) + offset ); memcpy( (char *)icmphr, (char *)icmph, len ); icmphr->type = ICMP_ECHOREPLY; icmphr->code = 0; icmphr->checksum = 0; if( icmph->checksum ) { /* Calculate Checksum */ icmphr->checksum = ip_compute_csum( (void *)icmphr, len ); } /* Ship it out - free it when done */ ip_queue_xmit( (volatile struct sock *)NULL, dev, skb, 1 ); skb1->sk = NULL; free_skb (skb1, FREE_READ); return( 0 ); default: PRINTK("\nUnsupported ICMP type = x%x", icmph->type ); skb1->sk = NULL; free_skb (skb1, FREE_READ); return( 0 ); /* just toss the packet */ } /* should be unecessary, but just in case. */ skb1->sk = NULL; free_skb (skb1, FREE_READ); return( 0 ); /* just toss the packet */ }
device_sound_interface &device_sound_interface::add_route(u32 output, speaker_device &target, double gain, u32 input, u32 mixoutput) { return add_route(output, target, DEVICE_SELF, gain, input, mixoutput); }
/** * loads the config data into shared memory (but doesn't really * share it), updates the routing data and writes it to the config * file. Afterwards, the global routing data is reloaded. * * @param opts pointer to the option structure which contains * data to be modified or to be added * * @return 0 on success, -1 on failure */ static int update_route_data(fifo_opt_t * opts) { struct rewrite_data * rd; int i,j; str tmp_domain; str tmp_prefix; str tmp_host; str tmp_rewrite_prefix; str tmp_rewrite_suffix; str tmp_comment = str_init(""); if ((rd = shm_malloc(sizeof(struct rewrite_data))) == NULL) { LM_ERR("out of shared memory\n"); return -1; } memset(rd, 0, sizeof(struct rewrite_data)); if (load_config(rd) < 0) { LM_ERR("could not load config\n"); FIFO_ERR(E_LOADCONF); return -1; } if (rule_fixup(rd) < 0) { LM_ERR("could not fixup rules\n"); FIFO_ERR(E_RULEFIXUP); return -1; } updated = 0; if (opts->cmd == OPT_ADD) { tmp_domain=opts->domain; tmp_prefix=opts->prefix; tmp_host=opts->host; tmp_rewrite_prefix=opts->rewrite_prefix; tmp_rewrite_suffix=opts->rewrite_suffix; if (tmp_domain.s==NULL) { tmp_domain.s=""; tmp_domain.len=0; } if (tmp_prefix.s==NULL) { tmp_prefix.s=""; tmp_prefix.len=0; } if (tmp_host.s==NULL) { tmp_host.s=""; tmp_host.len=0; } if (tmp_rewrite_prefix.s==NULL) { tmp_rewrite_prefix.s=""; tmp_rewrite_prefix.len=0; } if (tmp_rewrite_suffix.s==NULL) { tmp_rewrite_suffix.s=""; tmp_rewrite_suffix.len=0; } if (add_route(rd, 1, &tmp_domain, &tmp_prefix, 0, 0, 0, opts->prob, &tmp_host, opts->strip, &tmp_rewrite_prefix, &tmp_rewrite_suffix, opts->status, opts->hash_index, -1, NULL, &tmp_comment) < 0) { goto errout; } updated = 1; if (rule_fixup(rd) < 0) { LM_ERR("could not fixup rules after route appending\n"); FIFO_ERR(E_RULEFIXUP); return -1; } } else { for (i=0; i<rd->tree_num; i++) { if(rd->carriers[i]){ for (j=0; j<rd->carriers[i]->tree_num; j++) { if (rd->carriers[i]->trees[j] && rd->carriers[i]->trees[j]->tree) { if (update_route_data_recursor(rd->carriers[i]->trees[j]->tree, &rd->carriers[i]->trees[j]->name, opts) < 0) { goto errout; } } } } } } if(!updated){ LM_ERR("no match for update found\n"); FIFO_ERR(E_NOUPDATE); goto errout; } if (save_config(rd) < 0) { LM_ERR("could not save config\n"); FIFO_ERR(E_SAVECONF); goto errout; } if (prepare_route_tree() == -1) { LM_ERR("could not prepare the route tree\n"); FIFO_ERR(E_LOADCONF); goto errout; } destroy_rewrite_data(rd); return 0; errout: destroy_rewrite_data(rd); return -1; }
/** * Loads the routing data from the database given in global * variable db_url and stores it in routing tree rd. * * @param rd Pointer to the route data tree where the routing data * shall be loaded into * * @return 0 means ok, -1 means an error occured * */ int load_route_data(struct rewrite_data * rd) { db_res_t * res = NULL; db_row_t * row = NULL; int i, ret; int carrier_count = 0; struct carrier * carriers = NULL, * tmp = NULL; static str query_str; str tmp_carrier; str tmp_domain; str tmp_scan_prefix; str tmp_rewrite_host; str tmp_rewrite_prefix; str tmp_rewrite_suffix; str tmp_host_name; str tmp_reply_code; str tmp_next_domain; str tmp_comment; int no_rows=10; if( (strlen("SELECT DISTINCT FROM WHERE = ") + db_table.len + columns[COL_DOMAIN]->len + columns[COL_CARRIER]->len + 20) > QUERY_LEN) { LM_ERR("query too long\n"); return -1; } if((carrier_count = store_carriers(&carriers)) <= 0){ LM_ERR("error while retrieving carriers\n"); goto errout; } if ((rd->carriers = shm_malloc(sizeof(struct carrier_tree *) * carrier_count)) == NULL) { LM_ERR("out of shared memory\n"); goto errout; } memset(rd->carriers, 0, sizeof(struct carrier_tree *) * carrier_count); rd->tree_num = carrier_count; tmp = carriers; for (i=0; i<carrier_count; i++) { memset(query, 0, QUERY_LEN); ret = snprintf(query, QUERY_LEN, "SELECT DISTINCT %.*s FROM %.*s WHERE %.*s=%i", columns[COL_DOMAIN]->len, columns[COL_DOMAIN]->s, db_table.len, db_table.s, columns[COL_CARRIER]->len, columns[COL_CARRIER]->s, tmp->id); if (ret < 0) { LM_ERR("error in snprintf"); goto errout; } query_str.s = query; query_str.len = ret; if (dbf.raw_query(dbh, &query_str, &res) < 0) { LM_ERR("Failed to query database.\n"); goto errout; } LM_INFO("name %s, id %i, trees: %i\n", tmp->name, tmp->id, RES_ROW_N(res)); tmp_carrier.s=tmp->name; tmp_carrier.len=strlen(tmp_carrier.s); if (add_carrier_tree(&tmp_carrier, tmp->id, rd, RES_ROW_N(res)) == NULL) { LM_ERR("can't add carrier %s\n", tmp->name); goto errout; } dbf.free_result(dbh, res); res = NULL; tmp = tmp->next; } if (dbf.use_table(dbh, &db_table) < 0) { LM_ERR("Cannot set database table '%.*s'.\n", db_table.len, db_table.s); return -1; } if (DB_CAPABILITY(dbf, DB_CAP_FETCH)) { if (dbf.query(dbh, NULL, NULL, NULL, (db_key_t *) columns, 0, COLUMN_NUM, NULL, NULL) < 0) { LM_ERR("Failed to query database to prepare fetchrow.\n"); return -1; } no_rows = estimate_available_rows( 4+64+64+64+4+4+4+64+4+64+64+128, COLUMN_NUM); if (no_rows==0) no_rows = 10; if(dbf.fetch_result(dbh, &res, no_rows) < 0) { LM_ERR("Fetching rows failed\n"); return -1; } } else { if (dbf.query(dbh, NULL, NULL, NULL, (db_key_t *)columns, 0, COLUMN_NUM, NULL, &res) < 0) { LM_ERR("Failed to query database.\n"); return -1; } } int n = 0; do { LM_DBG("loading, cycle %d", n++); for (i = 0; i < RES_ROW_N(res); ++i) { row = &RES_ROWS(res)[i]; tmp_domain.s=(char *)row->values[COL_DOMAIN].val.string_val; tmp_scan_prefix.s=(char *)row->values[COL_SCAN_PREFIX].val.string_val; tmp_rewrite_host.s=(char *)row->values[COL_REWRITE_HOST].val.string_val; tmp_rewrite_prefix.s=(char *)row->values[COL_REWRITE_PREFIX].val.string_val; tmp_rewrite_suffix.s=(char *)row->values[COL_REWRITE_SUFFIX].val.string_val; tmp_comment.s=(char *)row->values[COL_COMMENT].val.string_val; if (tmp_domain.s==NULL) tmp_domain.s=""; if (tmp_scan_prefix.s==NULL) tmp_scan_prefix.s=""; if (tmp_rewrite_host.s==NULL) tmp_rewrite_host.s=""; if (tmp_rewrite_prefix.s==NULL) tmp_rewrite_prefix.s=""; if (tmp_rewrite_suffix.s==NULL) tmp_rewrite_suffix.s=""; if (tmp_comment.s==NULL) tmp_comment.s=""; tmp_domain.len=strlen(tmp_domain.s); tmp_scan_prefix.len=strlen(tmp_scan_prefix.s); tmp_rewrite_host.len=strlen(tmp_rewrite_host.s); tmp_rewrite_prefix.len=strlen(tmp_rewrite_prefix.s); tmp_rewrite_suffix.len=strlen(tmp_rewrite_suffix.s); tmp_comment.len=strlen(tmp_comment.s); if (add_route(rd, row->values[COL_CARRIER].val.int_val, &tmp_domain, &tmp_scan_prefix, row->values[COL_FLAGS].val.int_val, row->values[COL_MASK].val.int_val, 0, row->values[COL_PROB].val.double_val, &tmp_rewrite_host, row->values[COL_STRIP].val.int_val, &tmp_rewrite_prefix, &tmp_rewrite_suffix, 1, 0, -1, NULL, &tmp_comment) == -1) { goto errout; } } if (DB_CAPABILITY(dbf, DB_CAP_FETCH)) { if(dbf.fetch_result(dbh, &res, no_rows) < 0) { LM_ERR("fetching rows failed\n"); dbf.free_result(dbh, res); return -1; } } else { break; } } while(RES_ROW_N(res) > 0); dbf.free_result(dbh, res); res = NULL; if (dbf.use_table(dbh, &db_failure_table) < 0) { LM_ERR("cannot set database table '%.*s'.\n", db_failure_table.len, db_failure_table.s); return -1; } if (dbf.query(dbh, NULL, NULL, NULL, (db_key_t *)failure_columns, 0, FAILURE_COLUMN_NUM, NULL, &res) < 0) { LM_ERR("failed to query database.\n"); return -1; } for (i = 0; i < RES_ROW_N(res); ++i) { row = &RES_ROWS(res)[i]; tmp_domain.s=(char *)row->values[FCOL_DOMAIN].val.string_val; tmp_scan_prefix.s=(char *)row->values[FCOL_SCAN_PREFIX].val.string_val; tmp_host_name.s=(char *)row->values[FCOL_HOST_NAME].val.string_val; tmp_reply_code.s=(char *)row->values[FCOL_REPLY_CODE].val.string_val; tmp_next_domain.s=(char *)row->values[FCOL_NEXT_DOMAIN].val.string_val; tmp_comment.s=(char *)row->values[FCOL_COMMENT].val.string_val; if (tmp_domain.s==NULL) tmp_domain.s=""; if (tmp_scan_prefix.s==NULL) tmp_scan_prefix.s=""; if (tmp_host_name.s==NULL) tmp_host_name.s=""; if (tmp_reply_code.s==NULL) tmp_reply_code.s=""; if (tmp_next_domain.s==NULL) tmp_next_domain.s=""; if (tmp_comment.s==NULL) tmp_comment.s=""; tmp_domain.len=strlen(tmp_domain.s); tmp_scan_prefix.len=strlen(tmp_scan_prefix.s); tmp_host_name.len=strlen(tmp_host_name.s); tmp_reply_code.len=strlen(tmp_reply_code.s); tmp_next_domain.len=strlen(tmp_next_domain.s); tmp_comment.len=strlen(tmp_comment.s); if (add_failure_route(rd, row->values[FCOL_CARRIER].val.int_val, &tmp_domain, &tmp_scan_prefix, &tmp_host_name, &tmp_reply_code, row->values[FCOL_FLAGS].val.int_val, row->values[FCOL_MASK].val.int_val, &tmp_next_domain, &tmp_comment) == -1) { goto errout; } } destroy_carriers(carriers); dbf.free_result(dbh, res); return 0; errout: destroy_carriers(carriers); if (res) { dbf.free_result(dbh, res); } return -1; }
int main(int argc, char** argv) { if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) usage(0); int32 mode = RTM_LIST; if (argc > 1) { if (!strcmp(argv[1], "delete") || !strcmp(argv[1], "del") || !strcmp(argv[1], "-d")) { // delete route if (argc < 3) usage(1); mode = RTM_DELETE; } else if (!strcmp(argv[1], "add") || !strcmp(argv[1], "-a")) { // add route if (argc < 3) usage(1); mode = RTM_ADD; } else if (!strcmp(argv[1], "get")) { // get route for destination if (argc < 3) usage(1); mode = RTM_GET; } } int32 i = 2; int32 interfaceIndex = i; bool familySpecified = false; int32 familyIndex = 0; const char *interface = NULL; sockaddr_storage destination; sockaddr_storage mask; sockaddr_storage gateway; bool hasDestination = false, hasGateway = false, hasMask = false; bool defaultRoute = false; route_entry route; memset(&route, 0, sizeof(route_entry)); while (i < argc && i < 5) { // try to parse address family if (i <= 3 && familyIndex == -1 && get_address_family(argv[i], familyIndex)) { familySpecified = true; if (i == 2) interfaceIndex = -1; } if (!strcmp(argv[i], "default")) { defaultRoute = true; route.flags = RTF_DEFAULT; i++; break; } else if (parse_address(familyIndex, argv[i], destination)) { hasDestination = true; i++; break; } i++; } if (!defaultRoute && !hasDestination && mode != RTM_LIST) usage(1); if (i == 3) interfaceIndex = -1; if (interfaceIndex != -1 && interfaceIndex < argc) interface = argv[interfaceIndex]; if (i < argc && parse_address(familyIndex, argv[i], mask)) { hasMask = true; i++; } // parse options and flags while (i < argc) { if (!strcmp(argv[i], "gw") || !strcmp(argv[i], "gateway")) { if (!parse_address(familyIndex, argv[i + 1], gateway)) { fprintf(stderr, "%s: Option 'gw' needs valid address parameter\n", kProgramName); exit(1); } hasGateway = true; i++; } else if (!strcmp(argv[i], "nm") || !strcmp(argv[i], "netmask")) { if (hasMask) { fprintf(stderr, "%s: Netmask is specified twice\n", kProgramName); exit(1); } if (!parse_address(familyIndex, argv[i + 1], mask)) { fprintf(stderr, "%s: Option 'netmask' needs valid address parameter\n", kProgramName); exit(1); } hasMask = true; i++; } else if (!strcmp(argv[i], "mtu")) { route.mtu = argv[i + 1] ? strtol(argv[i + 1], NULL, 0) : 0; if (route.mtu <= 500) { fprintf(stderr, "%s: Option 'mtu' exptected valid max transfer unit size\n", kProgramName); exit(1); } i++; } else if (!strcmp(argv[i], "host")) { route.flags |= RTF_HOST; } else if (!strcmp(argv[i], "local")) { route.flags |= RTF_LOCAL; } else if (!strcmp(argv[i], "reject")) { route.flags |= RTF_REJECT; } else usage(1); i++; } if (hasDestination) route.destination = (sockaddr *)&destination; if (hasMask) route.mask = (sockaddr *)&mask; if (hasGateway) { route.gateway = (sockaddr *)&gateway; route.flags |= RTF_GATEWAY; } // we need a socket to talk to the networking stack int socket = ::socket(kFamilies[familyIndex].family, SOCK_DGRAM, 0); if (socket < 0) { fprintf(stderr, "%s: The requested address family is not available.\n", kProgramName); return 1; } switch (mode) { case RTM_ADD: if (interface == NULL) { fprintf(stderr, "%s: You need to specify an interface when adding a route.\n", kProgramName); usage(1); } add_route(socket, interface, route); break; case RTM_DELETE: if (interface == NULL) { fprintf(stderr, "%s: You need to specify an interface when removing a route.\n", kProgramName); usage(1); } delete_route(socket, interface, route); break; case RTM_LIST: if (familySpecified) list_routes(socket, interface, route); else { for (int32 i = 0; kFamilies[i].family >= 0; i++) { int socket = ::socket(kFamilies[familyIndex].family, SOCK_DGRAM, 0); if (socket < 0) continue; list_routes(socket, interface, route); close(socket); } } break; case RTM_GET: get_route(socket, route); break; } close(socket); return 0; }
/* * Creates the routes to send the traffic to the tun interface to be encapsulated */ int configure_routing_to_tun() { lispd_mapping_list *list = NULL; lispd_mapping_list *list_elt = NULL; lisp_addr_t *tun_v4_addr = NULL; lisp_addr_t *tun_v6_addr = NULL; lispd_mapping_elt *mapping = NULL; uint32_t iface_index = 0; if (tun_bring_up_iface(TUN_IFACE_NAME) != GOOD){ return (BAD); } if (router_mode == FALSE) { /* * For mobile node mode, we create two /1 routes covering the full IP addresses space to route all traffic * generated by the node to the lispTun0 interface * IPv4: 0.0.0.0/1 and 128.0.0.0/1 * IPv6: ::/1 and 8000::/1 */ tun_v4_addr = get_main_eid(AF_INET); tun_v6_addr = get_main_eid(AF_INET6); if (tun_v4_addr != NULL){ if (tun_add_eid_to_iface(*tun_v4_addr,TUN_IFACE_NAME) != GOOD){ return (BAD); } if (set_tun_default_route_v4() != GOOD){ return (BAD); } } if (tun_v6_addr != NULL){ if (tun_add_eid_to_iface(*tun_v6_addr,TUN_IFACE_NAME) != GOOD){ return (BAD); } if (set_tun_default_route_v6() != GOOD){ return (BAD); } } }else{ /* * For router mode, add a new routing table with default route to tun interface. Using source routing, * We send all traffic generated by EIDs to this table */ list = get_all_mappings(AF_UNSPEC); list_elt = list; /* Create rules to the new table */ while (list_elt != NULL){ mapping = list_elt->mapping; if (add_rule(mapping->eid_prefix.afi, 0, LISP_TABLE, RULE_TO_LISP_TABLE_PRIORITY, RTN_UNICAST, &(mapping->eid_prefix), mapping->eid_prefix_length, NULL,0,0)!=GOOD){ free_mapping_list(list, FALSE); return (BAD); } list_elt = list_elt->next; if (add_rule(mapping->eid_prefix.afi, 0, RT_TABLE_MAIN, RULE_AVOID_LISP_TABLE_PRIORITY, RTN_UNICAST, NULL,0, &(mapping->eid_prefix), mapping->eid_prefix_length, 0)!=GOOD){ free_mapping_list(list, FALSE); return (BAD); } } /* Add default route into the new table */ iface_index = if_nametoindex(TUN_IFACE_NAME); tun_v4_addr = get_main_eid(AF_INET); tun_v6_addr = get_main_eid(AF_INET6); if (tun_v4_addr != NULL){ add_route(AF_INET,iface_index,NULL,NULL,NULL,0,RULE_TO_LISP_TABLE_PRIORITY,LISP_TABLE); } if (tun_v6_addr != NULL){ add_route(AF_INET6,iface_index,NULL,NULL,NULL,0,RULE_TO_LISP_TABLE_PRIORITY,LISP_TABLE); } free_mapping_list(list, FALSE); } return (GOOD); }
int main( int argc, char **argv ) { uint8 anAddress[4]; uint8 anMask[4]; uint8 anGateway[4] = { 0, 0, 0, 0 }; const char *pzGateway = NULL, *pzProgram; const char *pzCommand, *pzNetAddr, *pzNetMask; struct rtentry sRoute; bool bLong = false; bool bNetSet = false, bMaskSet = false, bGwSet = false; int c; if ( (pzProgram = strrchr( *argv, '/' )) != NULL ) ++pzProgram; else pzProgram = *argv; memset( &sRoute, 0, sizeof( sRoute ) ); sRoute.rt_metric = 0; sRoute.rt_flags = RTF_UP | RTF_STATIC; /* Not necessary */ while ( ( c = getopt_long( argc, argv, "hlqvi:g:", long_opts, ( int * )0 ) ) != EOF ) { switch ( c ) { case 0: break; case 'l': bLong = true; break; case 'v': g_nShowVersion = true; break; case 'h': g_nShowHelp = true; break; default: usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } } argc -= optind; argv += optind; if ( (pzCommand = *argv++) == NULL ) { usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } /* Check command is valid */ if ( strcmp( pzCommand, "list" ) == 0 ) { list_routes( bLong ); return ( EXIT_SUCCESS ); } else if ( strcmp( pzCommand, "add" ) != 0 && strcmp( pzCommand, "del" ) != 0 ) { usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } /* Add or delete a route */ /* Look for address parameter */ while ( *argv ) { const char *pzInstruction = *argv++; char *pzArg = *argv++; if ( pzArg == NULL ) { /* No argument */ usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } if ( strcmp( pzInstruction, "net" ) == 0 ) { char *pzStr; if( bNetSet == true ) { usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } if( strcmp( pzArg, "default" ) == 0 ) { bNetSet = true; bMaskSet = true; } else { if( (pzStr = strchr( pzArg, '/' )) != NULL ) { /* CIDR notation in address parameter */ int nBits; uint32 nIpAddr = 0xFFFFFFFF; *pzStr++ = 0; if( (nBits = atoi( pzStr )) < 32 ) nIpAddr <<= (32 - nBits); *((uint32 *)&((struct sockaddr_in *)&sRoute.rt_genmask)->sin_addr) = htonl( nIpAddr ); bMaskSet = true; } /* Interpret as IP address */ parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_dst)->sin_addr, pzArg ); bNetSet = true; } } else if ( strcmp( pzInstruction, "mask" ) == 0 ) { if( bMaskSet == true ) { usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_genmask)->sin_addr, pzArg ); bMaskSet = true; } else if ( strcmp( pzInstruction, "gw" ) == 0 ) { if( bGwSet == true ) { usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } parse_ipaddress( (uint8*)&((struct sockaddr_in *)&sRoute.rt_gateway)->sin_addr, pzArg ); sRoute.rt_flags |= RTF_GATEWAY; bGwSet = true; } else { usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } } /* Check for required arguments */ if( !bNetSet || !bMaskSet ) { usage( pzProgram, 0 ); return ( EXIT_FAILURE ); } /* Perform action */ if ( strcmp( pzCommand, "add" ) == 0 ) { add_route( &sRoute ); } else if ( strcmp( pzCommand, "del" ) == 0 ) { del_route( &sRoute ); } return ( EXIT_SUCCESS ); }