/* * status = appOptionsHandler(cData, opt_index, opt_arg); * * This function is passed to skOptionsRegister(); it will be called * by skOptionsParse() for each user-specified switch that the * application has registered; it should handle the switch as * required---typically by setting global variables---and return 1 * if the switch processing failed or 0 if it succeeded. Returning * a non-zero from from the handler causes skOptionsParse() to return * a negative value. * * The clientData in 'cData' is typically ignored; 'opt_index' is * the index number that was specified as the last value for each * struct option in appOptions[]; 'opt_arg' is the user's argument * to the switch for options that have a REQUIRED_ARG or an * OPTIONAL_ARG. */ static int appOptionsHandler( clientData UNUSED(cData), int opt_index, char *opt_arg) { int rv; switch ((appOptionsEnum)opt_index) { case OPT_MAP_FILE: prefixmap_test_opt.map_file = opt_arg; break; case OPT_ADDRESS: rv = skStringParseIP(&prefixmap_test_opt.address, opt_arg); if (rv) { skAppPrintErr("Invalid %s '%s': %s", appOptions[opt_index].name, opt_arg, skStringParseStrerror(rv)); exit(EXIT_FAILURE); } prefixmap_test_opt.have_address = 1; break; case OPT_STRING: prefixmap_test_opt.string = 1; break; } return 0; /* OK */ }
static int processOneAddress( const char *addr) { char final_delim[] = {'\0', '\0'}; char cc[16]; char ipbuf[SK_NUM2DOT_STRLEN]; skipaddr_t ip; int rv; if (!app_opt.no_final_delimiter) { final_delim[0] = app_opt.column_separator; } rv = skStringParseIP(&ip, addr); if (rv) { skAppPrintErr("Invalid %s '%s': %s", appOptions[OPT_ADDRESS].name, addr, skStringParseStrerror(rv)); return 1; } #if SK_ENABLE_IPV6 if (skipaddrIsV6(&ip)) { skAppPrintErr("Invalid %s '%s': IPv6 addresses not supported", appOptions[OPT_ADDRESS].name, addr); return 1; } #endif /* SK_ENABLE_IPV6 */ skCountryLookupName(&ip, cc, sizeof(cc)); if (!app_opt.print_ips) { skStreamPrint(out, "%s\n", cc); } else { skipaddrString(ipbuf, &ip, ip_flags); if (app_opt.no_columns) { skStreamPrint(out, "%s%c%s%s\n", ipbuf, app_opt.column_separator, cc, final_delim); } else { skStreamPrint(out, "%15s%c%2s%s\n", ipbuf, app_opt.column_separator, cc, final_delim); } } return 0; }
/* * buildIPSetWildcards(stream); * * Read IP addresses from the stream named by 'stream' and use them * to build the global ipset. Allow the input to contain * IPWildcards. Return 0 on success or -1 on failure. */ static int buildIPSetWildcards( skstream_t *stream) { #if SK_ENABLE_IPV6 int saw_integer = 0; #endif int lc = 0; char line_buf[512]; skIPWildcard_t ipwild; skipaddr_t ip; uint32_t prefix; char *cp; int rv; /* read until end of file */ while ((rv = skStreamGetLine(stream, line_buf, sizeof(line_buf), &lc)) != SKSTREAM_ERR_EOF) { switch (rv) { case SKSTREAM_OK: /* good, we got our line */ break; case SKSTREAM_ERR_LONG_LINE: /* bad: line was longer than sizeof(line_buf) */ skAppPrintErr("Input line %d too long. ignored", lc); continue; default: /* unexpected error */ skStreamPrintLastErr(stream, rv, &skAppPrintErr); goto END; } /* first, attempt to parse as a CIDR block */ rv = skStringParseCIDR(&ip, &prefix, line_buf); if (rv == 0) { #if SK_ENABLE_IPV6 /* do not allow integers mixed with IPv6 addresses */ if (saw_integer) { if (skipaddrIsV6(&ip)) { skAppPrintErr("Error on line %d: %s", lc, SETBUILD_ERR_MIX_INT_V6); rv = -1; goto END; } } else if (SETBUILD_BUF_IS_INT(line_buf)) { saw_integer = 1; if (skIPSetIsV6(ipset)) { skAppPrintErr("Error on line %d: %s", lc, SETBUILD_ERR_MIX_INT_V6); rv = -1; goto END; } } #endif /* SK_ENABLE_IPV6 */ rv = skIPSetInsertAddress(ipset, &ip, prefix); if (rv) { skAppPrintErr("Error adding IP on line %d to IPset: %s", lc, skIPSetStrerror(rv)); goto END; } continue; } /* else parse the line as an IPWildcard */ rv = skStringParseIPWildcard(&ipwild, line_buf); if (rv != 0) { /* failed to parse an IPWildcard. See if the user has * entered two IP addresses, and if so, suggest they use * the --ip-ranges switch. */ int rv2; rv2 = skStringParseIP(&ip, line_buf); if (rv2 > 0) { /* parsed an IP and there is extra text after the IP * address; check to see if it is another IP addr */ #if SK_ENABLE_IPV6 if (skipaddrIsV6(&ip) && ((cp = strchr(line_buf + rv2, ':')) != NULL)) { while (isxdigit((int) *(cp - 1))) { --cp; } if (skStringParseIP(&ip, cp) == 0) { skAppPrintErr(("Invalid IP on line %d: " SUGGEST_IP_RANGES), lc); goto END; } } #endif if (!skipaddrIsV6(&ip) && ((cp = strchr(line_buf + rv2, '.')) != NULL)) { while (isxdigit((int) *(cp - 1))) { --cp; } if (skStringParseIP(&ip, cp) == 0) { skAppPrintErr(("Invalid IP on line %d: " SUGGEST_IP_RANGES), lc); goto END; } } } /* report initial error */ skAppPrintErr("Invalid IP Wildcard on line %d: %s", lc, skStringParseStrerror(rv)); goto END; } #if SK_ENABLE_IPV6 /* do not allow integers mixed with IPv6 addresses */ if (saw_integer && skIPWildcardIsV6(&ipwild)) { skAppPrintErr("Error on line %d: %s", lc, SETBUILD_ERR_MIX_INT_V6); rv = -1; goto END; } #endif /* SK_ENABLE_IPV6 */ rv = skIPSetInsertIPWildcard(ipset, &ipwild); if (rv) { skAppPrintErr("Error adding IP Wildcard on line %d to IPset: %s", lc, skIPSetStrerror(rv)); goto END; } } /* success */ rv = 0; END: if (rv != 0) { return -1; } return 0; }
/* * buildIPSetRanges(stream); * * Read IP addresses from the stream named by 'stream' and use them * to build the global ipset. Allow the input to support ranges of * IPs. Return 0 on success or -1 on failure. */ static int buildIPSetRanges( skstream_t *stream) { #if SK_ENABLE_IPV6 int saw_integer = 0; #endif int lc = 0; char line_buf[512]; char *sep; skipaddr_t ip; skipaddr_t ip_min; skipaddr_t ip_max; uint32_t prefix; const int delim_is_space = isspace((int)delimiter); int rv; /* read until end of file */ while ((rv = skStreamGetLine(stream, line_buf, sizeof(line_buf), &lc)) != SKSTREAM_ERR_EOF) { switch (rv) { case SKSTREAM_OK: /* good, we got our line */ break; case SKSTREAM_ERR_LONG_LINE: /* bad: line was longer than sizeof(line_buf) */ skAppPrintErr("Input line %d too long. ignored", lc); continue; default: /* unexpected error */ skStreamPrintLastErr(stream, rv, &skAppPrintErr); goto END; } /* support whitespace separators */ if (!delim_is_space) { sep = strchr(line_buf, delimiter); } else { /* ignore leading whitespace */ sep = line_buf; while (isspace((int)*sep)) { ++sep; } sep = strchr(sep, delimiter); if (sep) { /* allow a lone IP to have trailing whitespace */ char *cp = sep; while (isspace((int)*cp)) { ++cp; } if (*cp == '\0') { sep = NULL; } } } if (sep == NULL) { /* parse as IP with possible CIDR designation */ rv = skStringParseCIDR(&ip, &prefix, line_buf); if (rv != 0) { skAppPrintErr("Invalid IP on line %d: %s", lc, skStringParseStrerror(rv)); goto END; } #if SK_ENABLE_IPV6 /* do not allow integers mixed with IPv6 addresses */ if (saw_integer) { if (skipaddrIsV6(&ip)) { skAppPrintErr("Error on line %d: %s", lc, SETBUILD_ERR_MIX_INT_V6); rv = -1; goto END; } } else if (SETBUILD_BUF_IS_INT(line_buf)) { saw_integer = 1; if (skIPSetIsV6(ipset)) { skAppPrintErr("Error on line %d: %s", lc, SETBUILD_ERR_MIX_INT_V6); rv = -1; goto END; } } #endif /* SK_ENABLE_IPV6 */ rv = skIPSetInsertAddress(ipset, &ip, prefix); if (rv) { skAppPrintErr("Error adding IP on line %d to IPset: %s", lc, skIPSetStrerror(rv)); goto END; } continue; } /* parse two IP addresses */ *sep = '\0'; ++sep; rv = skStringParseIP(&ip_min, line_buf); if (rv != 0) { skAppPrintErr("Invalid minimum IP on line %d: %s", lc, skStringParseStrerror(rv)); goto END; } rv = skStringParseIP(&ip_max, sep); if (rv != 0) { skAppPrintErr("Invalid maximum IP on line %d: %s", lc, skStringParseStrerror(rv)); goto END; } if (skipaddrCompare(&ip_min, &ip_max) > 0) { skAppPrintErr("Invalid IP range on line %d: min > max", lc); rv = -1; goto END; } #if SK_ENABLE_IPV6 /* do not allow integers mixed with IPv6 addresses */ if (saw_integer) { if (skipaddrIsV6(&ip_min) || skipaddrIsV6(&ip_max)) { skAppPrintErr("Error on line %d: %s", lc, SETBUILD_ERR_MIX_INT_V6); rv = -1; goto END; } } else if (SETBUILD_BUF_IS_INT(line_buf) || SETBUILD_BUF_IS_INT(sep)) { saw_integer = 1; if (skIPSetIsV6(ipset)) { skAppPrintErr("Error on line %d: %s", lc, SETBUILD_ERR_MIX_INT_V6); rv = -1; goto END; } } #endif /* SK_ENABLE_IPV6 */ rv = skIPSetInsertRange(ipset, &ip_min, &ip_max); if (rv) { skAppPrintErr("Error adding IP range on line %d to IPset: %s", lc, skIPSetStrerror(rv)); goto END; } } /* success */ rv = 0; END: if (rv != 0) { return -1; } return 0; }