int splitCIDR(network_t *n, char *fullstring, char *ip, char *cidr) { ip = strtok(fullstring,"/"); cidr = strtok(NULL, "/"); // Validity checks: if ( ip == NULL || cidr == NULL ) { return 2; } int i_cidr = atoi(cidr); if ( i_cidr > 32 || i_cidr < 1 ) { return 2; } if ( setIPAddress(n, ip) != 1 ) { return 3; } convertCIDRToNetmask(n, i_cidr); return 1; }
/** * Combines a network and a host address by OR-ing all bits. * @param addr * The address to transform. * @return * TRUE if the net and host addresses are valid and do not overlap, FALS * otherwise. */ static BOOL combineAddresses(struct Address *network, struct Address const *host) { unsigned char *p1; unsigned char const *p2; unsigned char const *pnm; int num; struct Address netmask = *network; switch (network->type) { case AF_INET : p1 = (unsigned char *) &network->address.v4.s_addr; p2 = (unsigned char const *) &host->address.v4.s_addr; pnm = (unsigned char const *) &netmask.address.v4.s_addr; num = 4; break; case AF_INET6 : p1 = network->address.v6.s6_addr; p2 = host->address.v6.s6_addr; pnm = netmask.address.v6.s6_addr; num = 16; break; default : return FALSE; } if (!convertCIDRToNetmask(&netmask)) { return FALSE; } while (num-- > 0) { if ((*pnm & *p2) != 0) { network->type = ERR_COMBINATION_FAILED; return FALSE; } *p1 = (*p1 & *pnm) | *p2; ++p1; ++p2; ++pnm; } return TRUE; }
/** * Main entry point. * @param argc * The number of arguments. * @param argv * The array containing all arguments. */ int main(int argc, char *argv[]) { struct Address addr; char const *err = NULL; int minArg; if (argc < 3 || argc > 5) { return usage(argv[0]); } if (strcmp(argv[1], "isip") == 0) { if (argc == 3) { parseAddressWithoutMask(argv[2], &addr); return isValidAddress(&addr) ? 0 : 1; } else { return usage(argv[0]); } } if (strcmp(argv[1], "isipv4") == 0) { if (argc == 3) { parseAddressWithoutMask(argv[2], &addr); return addr.type == AF_INET ? 0 : 1; } else { return usage(argv[0]); } } if (strcmp(argv[1], "isipv6") == 0) { if (argc == 3) { parseAddressWithoutMask(argv[2], &addr); return addr.type == AF_INET6 ? 0 : 1; } else { return usage(argv[0]); } } if (strcmp(argv[1], "netmask") == 0) { if (argc == 3) { if (parseAddressWithMask(argv[2], &addr)) { convertCIDRToNetmask(&addr); } return makeResult(&addr, argv[2], FALSE); } else { return usage(argv[0]); } } if (strcmp(argv[1], "netmaskbits") == 0) { if (argc == 3) { if (parseAddressWithoutMask(argv[2], &addr)) { convertNetmaskToCIDR(&addr); } else { parseAddressWithMask(argv[2], &addr); } if (isValidAddress(&addr)) { printf("%u\n", addr.netmaskbits); return 0; } else { return makeResult(&addr, argv[2], FALSE); } } else { return usage(argv[0]); } } if (strcmp(argv[1], "combine") == 0) { minArg = 4; } else { minArg = 3; } if (argc < minArg || argc > minArg + 1) { return usage(argv[0]); } else if (argc == minArg) { parseAddressWithMask(argv[2], &addr); err = argv[2]; } else { if (parseAddressWithoutMask(argv[2], &addr)) { struct Address mask; if (parseAddressWithoutMask(argv[3], &mask) && convertNetmaskToCIDR(&mask)) { if (addr.type == mask.type) { addr.netmaskbits = mask.netmaskbits; } else { fprintf(stderr, "address and netmask must belong to the same address family\n"); return -ERR_INVALID_NETMASK + 1; } } else { err = argv[3]; addr.type = mask.type == ERR_INVALID_ADDRESS ? ERR_INVALID_NETMASK : mask.type; } } else if (parseAddressWithMask(argv[2], &addr)) { return usage(argv[0]); } else { err = argv[2]; } } if (strcmp(argv[1], "canonicalize") == 0) { return makeResult(&addr, err, TRUE); } if (strcmp(argv[1], "network") == 0) { if (isValidAddress(&addr)) { convertCIDRToNetwork(&addr); err = argv[2]; } return makeResult(&addr, err, FALSE); } if (strcmp(argv[1], "host") == 0) { if (isValidAddress(&addr)) { convertCIDRToHost(&addr); err = argv[2]; } return makeResult(&addr, err, FALSE); } if (strcmp(argv[1], "broadcast") == 0) { if (addr.type == AF_INET6) { printf("ff02::1\n"); return 0; } else { if (isValidAddress(&addr)) { convertCIDRToBroadcast(&addr); err = argv[2]; } return makeResult(&addr, err, FALSE); } } if (strcmp(argv[1], "dnsrev") == 0) { if (isValidAddress(&addr) && convertCIDRToNetwork(&addr)) { char *str = buildReverseDNSName(&addr); if (str) { printf("%s\n", str); free(str); return 0; } else { fprintf(stderr, "conversion to DNS name failed\n"); return -ERR_DNS_CONVERSION_FAILED + 1; } } else { return makeResult(&addr, err, FALSE); } } if (strcmp(argv[1], "combine") == 0) { struct Address addr2; if (isValidAddress(&addr)) { if (parseAddressWithoutMask(argv[argc - 1], &addr2)) { if (addr.type == addr2.type) { combineAddresses(&addr, &addr2); return makeResult(&addr, argv[2], TRUE); } else { fprintf(stderr, "addresses to be combined must belong to the same address family\n"); return -ERR_INVALID_ADDRESS + 1; } } else { return makeResult(&addr2, argv[argc - 1], FALSE); } } else { return makeResult(&addr, err, FALSE); } } // from old source: if (! strcmp (argv[1], "dnsnet")) { if (isValidAddress(&addr)) { return (dnsnet (argc, argv)); } } return usage(argv[0]); }