errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx) { struct cache_tool_ctx *ctx = NULL; int idb = INVALIDATE_NONE; char *user = NULL; char *group = NULL; char *netgroup = NULL; char *service = NULL; char *map = NULL; char *domain = NULL; int debug = SSSDBG_DEFAULT; errno_t ret = EOK; poptContext pc = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &debug, 0, _("The debug level to run with"), NULL }, { "everything", 'E', POPT_ARG_NONE, NULL, 'e', _("Invalidate all cached entries except for sudo rules"), NULL }, { "user", 'u', POPT_ARG_STRING, &user, 0, _("Invalidate particular user"), NULL }, { "users", 'U', POPT_ARG_NONE, NULL, 'u', _("Invalidate all users"), NULL }, { "group", 'g', POPT_ARG_STRING, &group, 0, _("Invalidate particular group"), NULL }, { "groups", 'G', POPT_ARG_NONE, NULL, 'g', _("Invalidate all groups"), NULL }, { "netgroup", 'n', POPT_ARG_STRING, &netgroup, 0, _("Invalidate particular netgroup"), NULL }, { "netgroups", 'N', POPT_ARG_NONE, NULL, 'n', _("Invalidate all netgroups"), NULL }, { "service", 's', POPT_ARG_STRING, &service, 0, _("Invalidate particular service"), NULL }, { "services", 'S', POPT_ARG_NONE, NULL, 's', _("Invalidate all services"), NULL }, #ifdef BUILD_AUTOFS { "autofs-map", 'a', POPT_ARG_STRING, &map, 0, _("Invalidate particular autofs map"), NULL }, { "autofs-maps", 'A', POPT_ARG_NONE, NULL, 'a', _("Invalidate all autofs maps"), NULL }, #endif /* BUILD_AUTOFS */ { "domain", 'd', POPT_ARG_STRING, &domain, 0, _("Only invalidate entries from a particular domain"), NULL }, POPT_TABLEEND }; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); goto fini; } pc = poptGetContext(NULL, argc, argv, long_options, 0); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'u': idb |= INVALIDATE_USERS; break; case 'g': idb |= INVALIDATE_GROUPS; break; case 'n': idb |= INVALIDATE_NETGROUPS; break; case 's': idb |= INVALIDATE_SERVICES; break; case 'a': idb |= INVALIDATE_AUTOFSMAPS; break; case 'e': idb = INVALIDATE_EVERYTHING; break; } } DEBUG_CLI_INIT(debug); debug_prg_name = argv[0]; if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } if (idb == INVALIDATE_NONE && !user && !group && !netgroup && !service && !map) { BAD_POPT_PARAMS(pc, _("Please select at least one object to invalidate\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ctx = talloc_zero(NULL, struct cache_tool_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for tools context\n"); ret = ENOMEM; goto fini; } if (idb & INVALIDATE_USERS) { ctx->user_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_user_filter = false; } else if (user) { ctx->user_name = talloc_strdup(ctx, user); ctx->update_user_filter = true; } if (idb & INVALIDATE_GROUPS) { ctx->group_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_group_filter = false; } else if (group) { ctx->group_name = talloc_strdup(ctx, group); ctx->update_group_filter = true; } if (idb & INVALIDATE_NETGROUPS) { ctx->netgroup_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_netgroup_filter = false; } else if (netgroup) { ctx->netgroup_name = talloc_strdup(ctx, netgroup); ctx->update_netgroup_filter = true; } if (idb & INVALIDATE_SERVICES) { ctx->service_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_service_filter = false; } else if (service) { ctx->service_name = talloc_strdup(ctx, service); ctx->update_service_filter = true; } if (idb & INVALIDATE_AUTOFSMAPS) { ctx->autofs_filter = talloc_asprintf(ctx, "(&(objectclass=%s)(%s=*))", SYSDB_AUTOFS_MAP_OC, SYSDB_NAME); ctx->update_autofs_filter = false; } else if (map) { ctx->autofs_name = talloc_strdup(ctx, map); ctx->update_autofs_filter = true; } if (((idb & INVALIDATE_USERS) && !ctx->user_filter) || ((idb & INVALIDATE_GROUPS) && !ctx->group_filter) || ((idb & INVALIDATE_NETGROUPS) && !ctx->netgroup_filter) || ((idb & INVALIDATE_SERVICES) && !ctx->service_filter) || ((idb & INVALIDATE_AUTOFSMAPS) && !ctx->autofs_filter) || (user && !ctx->user_name) || (group && !ctx->group_name) || (netgroup && !ctx->netgroup_name) || (map && !ctx->autofs_name) || (service && !ctx->service_name)) { DEBUG(SSSDBG_CRIT_FAILURE, "Construction of filters failed\n"); ret = ENOMEM; goto fini; } ret = init_domains(ctx, domain); if (ret != EOK) { if (domain) { ERROR("Could not open domain %1$s. If the domain is a subdomain " "(trusted domain), use fully qualified name instead of " "--domain/-d parameter.\n", domain); } else { ERROR("Could not open available domains\n"); } DEBUG(SSSDBG_OP_FAILURE, "Initialization of sysdb connections failed\n"); goto fini; } ret = EOK; fini: poptFreeContext(pc); free(user); free(group); free(netgroup); free(domain); if (ret != EOK && ctx) { talloc_zfree(ctx); } if (ret == EOK) { *tctx = ctx; } return ret; }
status_t init_stack() { status_t status = init_domains(); if (status != B_OK) return status; status = init_interfaces(); if (status != B_OK) goto err1; status = init_device_interfaces(); if (status != B_OK) goto err2; status = init_timers(); if (status != B_OK) goto err3; status = init_notifications(); if (status < B_OK) { // If this fails, it just means there won't be any notifications, // it's not a fatal error. dprintf("networking stack notifications could not be initialized: %s\n", strerror(status)); } module_info* dummy; status = get_module(NET_SOCKET_MODULE_NAME, &dummy); if (status != B_OK) goto err4; mutex_init(&sChainLock, "net chains"); mutex_init(&sInitializeChainLock, "net intialize chains"); sFamilies = new(std::nothrow) FamilyTable(); if (sFamilies == NULL || sFamilies->Init(10) != B_OK) { status = B_NO_MEMORY; goto err5; } sProtocolChains = new(std::nothrow) ChainTable(); if (sProtocolChains == NULL || sProtocolChains->Init(10) != B_OK) { status = B_NO_MEMORY; goto err6; } sDatalinkProtocolChains = new(std::nothrow) ChainTable(); if (sDatalinkProtocolChains == NULL || sDatalinkProtocolChains->Init(10) != B_OK) { status = B_NO_MEMORY; goto err7; } sReceivingProtocolChains = new(std::nothrow) ChainTable(); if (sReceivingProtocolChains == NULL || sReceivingProtocolChains->Init(10) != B_OK) { status = B_NO_MEMORY; goto err8; } sInitialized = true; link_init(); scan_modules("network/protocols"); scan_modules("network/datalink_protocols"); // TODO: for now! register_domain_datalink_protocols(AF_INET, IFT_LOOP, "network/datalink_protocols/loopback_frame/v1", NULL); #if 0 // PPP is not (currently) included in the build register_domain_datalink_protocols(AF_INET, IFT_PPP, "network/datalink_protocols/ppp_frame/v1", NULL); #endif register_domain_datalink_protocols(AF_INET6, IFT_LOOP, "network/datalink_protocols/loopback_frame/v1", NULL); register_domain_datalink_protocols(AF_INET, IFT_ETHER, "network/datalink_protocols/arp/v1", "network/datalink_protocols/ethernet_frame/v1", NULL); register_domain_datalink_protocols(AF_INET6, IFT_ETHER, "network/datalink_protocols/ipv6_datagram/v1", "network/datalink_protocols/ethernet_frame/v1", NULL); return B_OK; err8: delete sDatalinkProtocolChains; err7: delete sProtocolChains; err6: delete sFamilies; err5: mutex_destroy(&sInitializeChainLock); mutex_destroy(&sChainLock); err4: uninit_timers(); err3: uninit_device_interfaces(); err2: uninit_interfaces(); err1: uninit_domains(); return status; }
void parse(char *country_input, char *path_input, char *domain_input, char *ipaddress_input, char *http_status_input, char *referer_input, char *bird, char *db_path, int minimum_field_count) { // GENERIC VARIABLES char *fields[MAX_FIELD_CNT]; // number of fields we expect in a single line int num_filters = 0; // total number of filters we detect from the command line int num_domain_filters = 0; // total number of domain filters int num_path_filters = 0; // total number of path filters int num_ipaddress_filters = 0; // total number of ipaddress filter int num_countries_filters = 0; // total number countries we want to restrict the filtering int num_http_status_filters = 0; // total number of http status we want to restrict the filtering. int num_referer_filters = 0; int required_hits = 0; int bird_int = 0; int i; int field_count_this_line=0; // number of fields found in the current line char line[ LINE_BUF_SIZE ]; char *ipaddr; char *url; char *http_status; char *referer; // DETERMINE NUMBER OF FILTERS if(params[DOMAIN_FILTER]){ num_domain_filters = determine_num_obs(domain_input,comma_delimiter); required_hits+=1; } if(params[PATH_FILTER]){ num_path_filters = determine_num_obs(path_input,comma_delimiter); required_hits+=1; } if(params[IP_FILTER]){ num_ipaddress_filters = determine_num_obs(ipaddress_input, comma_delimiter); required_hits+=1; } if(params[GEO_FILTER]){ if(country_input != NULL && strlen(country_input) >1){ num_countries_filters = determine_num_obs(country_input, comma_delimiter); required_hits+=1; } } if(params[REFERER_FILTER]){ num_referer_filters = determine_num_obs(referer_input, comma_delimiter); required_hits+=1; } if(params[HTTP_STATUS_FILTER]){ if(http_status_input != NULL && strlen(http_status_input) >1){ num_http_status_filters = determine_num_obs(http_status_input, comma_delimiter); required_hits+=1; } } num_filters = num_path_filters + num_domain_filters + num_ipaddress_filters + num_countries_filters + num_http_status_filters + num_referer_filters; Filter filters[num_filters]; // GEO_FILTER INITIALIZATION GeoIP *gi = NULL; // initialize to suppress compiler warning char *countries[num_countries_filters]; char *area; // FILTER INITIALIZATION if(params[DOMAIN_FILTER]){ init_domains(filters, domain_input, comma_delimiter); } else { domain_input=NULL; } if(params[PATH_FILTER]){ init_paths(filters, path_input, comma_delimiter); } else { path_input = NULL; } if(params[IP_FILTER]){ init_ip_addresses(filters, ipaddress_input, comma_delimiter); } else { ipaddress_input = NULL; } if (params[REFERER_FILTER]){ init_domains(filters, referer_input, comma_delimiter); } else { referer_input = NULL; } if( ! (params[GEO_FILTER] || (recode & GEO)) ) { country_input = NULL; } else { init_countries(countries, country_input, num_countries_filters, comma_delimiter); bird_int = init_bird_level(bird); /* * Before changing the type of cache, have a look at this benchmark: * http://www.maxmind.com/app/benchmark * and choose wisely. */ switch(bird_int){ case COUNTRY: if(db_path!=NULL){ db_country_path=db_path; } gi = GeoIP_open(db_country_path, GEOIP_MEMORY_CACHE); break; case REGION: if(db_path!=NULL){ db_region_path=db_path; } gi = GeoIP_open(db_region_path, GEOIP_MEMORY_CACHE); break; case CITY: if(db_path!=NULL){ db_city_path=db_path; } gi = GeoIP_open(db_city_path, GEOIP_MEMORY_CACHE); break; case LAT_LON: if(db_path!=NULL){ db_city_path=db_path; } gi = GeoIP_open(db_city_path, GEOIP_MEMORY_CACHE); break; case EVERYTHING: if(db_path!=NULL){ db_city_path=db_path; } gi = GeoIP_open(db_city_path, GEOIP_MEMORY_CACHE); break; } if (gi == NULL) { fprintf(stderr, "Error opening MaxMind Geo database.\n"); fprintf(stderr, "Path used for country database:%s\n", db_country_path); fprintf(stderr, "Path used for region database:%s\n", db_region_path); fprintf(stderr, "Path used for city database:%s\n", db_city_path); exit(EXIT_FAILURE); } else { if(verbose_flag){ char *db_info =GeoIP_database_info(gi); unsigned char db_edition = GeoIP_database_edition(gi); GeoIPDBTypes geodbtype = (GeoIPDBTypes)db_info; fprintf(stderr,"Maxmind database: %i; version: %i\n", db_edition, geodbtype); } } } if(params[HTTP_STATUS_FILTER]){ init_http_status(filters, http_status_input, comma_delimiter); } else { http_status_input = NULL; } if (verbose_flag){ fprintf(stderr, "num_path_filters:%d\tnum_domain_filters:%d" "\tnum_http_status_filters:%d\tip_address_count:%d" "\tcountries_count:%d\treferer_count:%d\n", num_path_filters, num_domain_filters, num_http_status_filters, num_ipaddress_filters, num_countries_filters, num_referer_filters); } // Now that we have initilaized all the filters, // do the actual filtering and conversion of the // incoming data. while ( true ) { int found =0; area = NULL; char *r; r=fgets(line, LINE_BUF_SIZE, stdin); if(!r) { break; } i = 0; char *p; do { fields[i] = r; //strsep(&r, ws_delimiter); p = strchr( r, *ws_delimiter ); i++; if ( NULL == p ) break; *p = 0; r = p + 1; } while (i < MAX_FIELD_CNT); if (i < minimum_field_count || i == MAX_FIELD_CNT){ continue; // ignore line since field count is outside expected range } // we found i fields in this line. field_count_this_line = i; ipaddr = fields[4]; http_status = fields[5]; url = fields[8]; referer = fields[11]; //ua = fields[13]; // necessary for bot detection if (url != NULL) { if (params[DOMAIN_FILTER]){ found += match_domain(url, filters, num_domain_filters,verbose_flag); } if (params[PATH_FILTER]){ found += match_path(url, filters, num_path_filters,verbose_flag); } if (params[HTTP_STATUS_FILTER]){ found += match_http_status(http_status, filters, num_http_status_filters,verbose_flag); } if (params[IP_FILTER]){ found += match_ip_address(ipaddr, filters, num_ipaddress_filters,verbose_flag); } if (params[REFERER_FILTER]){ found += match_domain(referer, filters, num_referer_filters,verbose_flag); } if (params[GEO_FILTER]){ area = geo_lookup(gi, ipaddr, bird_int); found += geo_check(area, countries, num_countries_filters,verbose_flag); if (verbose_flag){ fprintf(stderr, "IP address: %s was geocoded as: %s\n", ipaddr, area); } } } // required_hits will equal the number of filters // given. These include ip, domain, path, status, // and country filtering. If no filters were given, // then found will be 0 AND require_hits will be 0, // allowing the line to pass through. if (found >= required_hits) { // if we need to replace the IP addr // because recode is GEO or ANONYMIZE or both if (recode) { // geocode if we haven't already geocoded and // we'll be needing the geocoded string when // replacing the IP. if (area == NULL && (recode & GEO)) { area = geo_lookup(gi, ipaddr, bird_int); } // replace the ip address in fields. // if area is not null, it will be appended // to the ip address. If (recode & ANONYMIZE) is // true, then the IP will be replaced. replace_ip_addr(fields, area, (recode & ANONYMIZE)); } // print output to stdout for (i=0;i<field_count_this_line;++i){ if (i!=0){ FPUTS(ws_delimiter, stdout); } FPUTS(fields[i], stdout); } } if (verbose_flag) { fprintf(stderr, "ipaddr: '%s', url: '%s, status: %s'\n", ipaddr, url, http_status); } } free_memory(filters, path_input, domain_input,num_filters, gi, countries, num_countries_filters); }
static errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx) { struct cache_tool_ctx *ctx = NULL; int idb = INVALIDATE_NONE; struct input_values values = { 0 }; int debug = SSSDBG_DEFAULT; errno_t ret = EOK; poptContext pc = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &debug, 0, _("The debug level to run with"), NULL }, { "everything", 'E', POPT_ARG_NONE, NULL, 'e', _("Invalidate all cached entries"), NULL }, { "user", 'u', POPT_ARG_STRING, &(values.user), 0, _("Invalidate particular user"), NULL }, { "users", 'U', POPT_ARG_NONE, NULL, 'u', _("Invalidate all users"), NULL }, { "group", 'g', POPT_ARG_STRING, &(values.group), 0, _("Invalidate particular group"), NULL }, { "groups", 'G', POPT_ARG_NONE, NULL, 'g', _("Invalidate all groups"), NULL }, { "netgroup", 'n', POPT_ARG_STRING, &(values.netgroup), 0, _("Invalidate particular netgroup"), NULL }, { "netgroups", 'N', POPT_ARG_NONE, NULL, 'n', _("Invalidate all netgroups"), NULL }, { "service", 's', POPT_ARG_STRING, &(values.service), 0, _("Invalidate particular service"), NULL }, { "services", 'S', POPT_ARG_NONE, NULL, 's', _("Invalidate all services"), NULL }, #ifdef BUILD_AUTOFS { "autofs-map", 'a', POPT_ARG_STRING, &(values.map), 0, _("Invalidate particular autofs map"), NULL }, { "autofs-maps", 'A', POPT_ARG_NONE, NULL, 'a', _("Invalidate all autofs maps"), NULL }, #endif /* BUILD_AUTOFS */ #ifdef BUILD_SSH { "ssh-host", 'h', POPT_ARG_STRING, &(values.ssh_host), 0, _("Invalidate particular SSH host"), NULL }, { "ssh-hosts", 'H', POPT_ARG_NONE, NULL, 'h', _("Invalidate all SSH hosts"), NULL }, #endif /* BUILD_SSH */ #ifdef BUILD_SUDO { "sudo-rule", 'r', POPT_ARG_STRING, &(values.sudo_rule), 0, _("Invalidate particular sudo rule"), NULL }, { "sudo-rules", 'R', POPT_ARG_NONE, NULL, 'r', _("Invalidate all cached sudo rules"), NULL }, #endif /* BUILD_SUDO */ { "domain", 'd', POPT_ARG_STRING, &(values.domain), 0, _("Only invalidate entries from a particular domain"), NULL }, POPT_TABLEEND }; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); goto fini; } pc = poptGetContext(NULL, argc, argv, long_options, 0); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'u': idb |= INVALIDATE_USERS; break; case 'g': idb |= INVALIDATE_GROUPS; break; case 'n': idb |= INVALIDATE_NETGROUPS; break; case 's': idb |= INVALIDATE_SERVICES; break; case 'a': idb |= INVALIDATE_AUTOFSMAPS; break; case 'h': idb |= INVALIDATE_SSH_HOSTS; break; case 'r': idb |= INVALIDATE_SUDO_RULES; break; case 'e': idb = INVALIDATE_EVERYTHING; #ifdef BUILD_SUDO idb |= INVALIDATE_SUDO_RULES; #endif /* BUILD_SUDO */ break; } } DEBUG_CLI_INIT(debug); debug_prg_name = argv[0]; if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } if (poptGetArg(pc)) { BAD_POPT_PARAMS(pc, _("Unexpected argument(s) provided, options that " "invalidate a single object only accept a single " "provided argument.\n"), ret, fini); } if (idb == INVALIDATE_NONE && !values.user && !values.group && !values.netgroup && !values.service && !values.map && !values.ssh_host && !values.sudo_rule) { BAD_POPT_PARAMS(pc, _("Please select at least one object to invalidate\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ctx = talloc_zero(NULL, struct cache_tool_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for tools context\n"); ret = ENOMEM; goto fini; } if (idb & INVALIDATE_USERS) { ctx->user_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_user_filter = false; } else if (values.user) { ctx->user_name = talloc_strdup(ctx, values.user); ctx->update_user_filter = true; } if (idb & INVALIDATE_GROUPS) { ctx->group_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_group_filter = false; } else if (values.group) { ctx->group_name = talloc_strdup(ctx, values.group); ctx->update_group_filter = true; } if (idb & INVALIDATE_NETGROUPS) { ctx->netgroup_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_netgroup_filter = false; } else if (values.netgroup) { ctx->netgroup_name = talloc_strdup(ctx, values.netgroup); ctx->update_netgroup_filter = true; } if (idb & INVALIDATE_SERVICES) { ctx->service_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_service_filter = false; } else if (values.service) { ctx->service_name = talloc_strdup(ctx, values.service); ctx->update_service_filter = true; } if (idb & INVALIDATE_AUTOFSMAPS) { ctx->autofs_filter = talloc_asprintf(ctx, "(&(objectclass=%s)(%s=*))", SYSDB_AUTOFS_MAP_OC, SYSDB_NAME); ctx->update_autofs_filter = false; } else if (values.map) { ctx->autofs_name = talloc_strdup(ctx, values.map); ctx->update_autofs_filter = true; } if (idb & INVALIDATE_SSH_HOSTS) { ctx->ssh_host_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_ssh_host_filter = false; } else if (values.ssh_host) { ctx->ssh_host_name = talloc_strdup(ctx, values.ssh_host); ctx->update_ssh_host_filter = true; } if (idb & INVALIDATE_SUDO_RULES) { ctx->sudo_rule_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_sudo_rule_filter = false; } else if (values.sudo_rule) { ctx->sudo_rule_name = talloc_strdup(ctx, values.sudo_rule); ctx->update_sudo_rule_filter = true; } if (is_filter_valid(ctx, &values, idb) == false) { DEBUG(SSSDBG_CRIT_FAILURE, "Construction of filters failed\n"); ret = ENOMEM; goto fini; } ret = init_domains(ctx, values.domain); if (ret != EOK) { if (values.domain) { ERROR("Could not open domain %1$s. If the domain is a subdomain " "(trusted domain), use fully qualified name instead of " "--domain/-d parameter.\n", values.domain); } else { ERROR("Could not open available domains\n"); } DEBUG(SSSDBG_OP_FAILURE, "Initialization of sysdb connections failed\n"); goto fini; } ret = EOK; fini: poptFreeContext(pc); free_input_values(&values); if (ret != EOK && ctx) { talloc_zfree(ctx); } if (ret == EOK) { *tctx = ctx; } return ret; }
status_t init_stack() { status_t status = init_domains(); if (status != B_OK) return status; status = init_interfaces(); if (status != B_OK) goto err1; status = init_device_interfaces(); if (status != B_OK) goto err2; status = init_timers(); if (status != B_OK) goto err3; status = init_notifications(); if (status < B_OK) { // If this fails, it just means there won't be any notifications, // it's not a fatal error. dprintf("networking stack notifications could not be initialized: %s\n", strerror(status)); } module_info* dummy; status = get_module(NET_SOCKET_MODULE_NAME, &dummy); if (status != B_OK) goto err4; mutex_init(&sChainLock, "net chains"); mutex_init(&sInitializeChainLock, "net intialize chains"); sFamilies = hash_init(10, offsetof(struct family, next), &family::Compare, &family::Hash); if (sFamilies == NULL) { status = B_NO_MEMORY; goto err5; } sProtocolChains = hash_init(10, offsetof(struct chain, next), &chain::Compare, &chain::Hash); if (sProtocolChains == NULL) { status = B_NO_MEMORY; goto err6; } sDatalinkProtocolChains = hash_init(10, offsetof(struct chain, next), &chain::Compare, &chain::Hash); if (sDatalinkProtocolChains == NULL) { status = B_NO_MEMORY; goto err7; } sReceivingProtocolChains = hash_init(10, offsetof(struct chain, next), &chain::Compare, &chain::Hash); if (sReceivingProtocolChains == NULL) { status = B_NO_MEMORY; goto err8; } sInitialized = true; link_init(); scan_modules("network/protocols"); scan_modules("network/datalink_protocols"); // TODO: for now! register_domain_datalink_protocols(AF_INET, IFT_LOOP, "network/datalink_protocols/loopback_frame/v1", NULL); register_domain_datalink_protocols(AF_INET6, IFT_LOOP, "network/datalink_protocols/loopback_frame/v1", NULL); register_domain_datalink_protocols(AF_INET, IFT_ETHER, "network/datalink_protocols/arp/v1", "network/datalink_protocols/ethernet_frame/v1", NULL); register_domain_datalink_protocols(AF_INET6, IFT_ETHER, "network/datalink_protocols/ipv6_datagram/v1", "network/datalink_protocols/ethernet_frame/v1", NULL); return B_OK; err8: hash_uninit(sDatalinkProtocolChains); err7: hash_uninit(sProtocolChains); err6: hash_uninit(sFamilies); err5: mutex_destroy(&sInitializeChainLock); mutex_destroy(&sChainLock); err4: uninit_timers(); err3: uninit_device_interfaces(); err2: uninit_interfaces(); err1: uninit_domains(); return status; }