/* * Use some locking here... */ int ni_dhcp6_load_duid(ni_opaque_t *duid, const char *filename) { char path[PATH_MAX]; const char *name = CONFIG_DHCP6_DUID_NODE; xml_node_t *xml = NULL; xml_node_t *node; FILE *fp; int rv; if (!filename) { snprintf(path, sizeof(path), "%s/%s", ni_config_storedir(), CONFIG_DHCP6_DUID_FILE); filename = path; } else { name = "duid"; } if ((fp = fopen(filename, "r")) == NULL) { if (errno != ENOENT) ni_error("unable to open %s for reading: %m", filename); return -1; } xml = xml_node_scan(fp, NULL); fclose(fp); if (xml == NULL) { ni_error("%s: unable to parse xml file", filename); return -1; } if (xml->name == NULL) node = xml->children; else node = xml; if (!node || !ni_string_eq(node->name, name)) { ni_error("%s: does not contain %s", filename, name); xml_node_free(xml); return -1; } rv = 0; if (!node->cdata || !ni_duid_parse_hex(duid, node->cdata)) { ni_error("%s: unable to parse %s xml file", filename, name); rv = -1; } xml_node_free(xml); return rv; }
int ni_dhcp6_lease_data_from_xml(ni_addrconf_lease_t *lease, const xml_node_t *node, const char *ifname) { const char *ia_na_name = ni_dhcp6_option_name(NI_DHCP6_OPTION_IA_NA); const char *ia_ta_name = ni_dhcp6_option_name(NI_DHCP6_OPTION_IA_TA); const char *ia_pd_name = ni_dhcp6_option_name(NI_DHCP6_OPTION_IA_PD); unsigned int value; ni_sockaddr_t addr; xml_node_t *child; if (!lease || !node) return -1; lease->dhcp6.rapid_commit = FALSE; for (child = node->children; child; child = child->next) { if (ni_string_eq(child->name, "client-id") && child->cdata) { if (!ni_duid_parse_hex(&lease->dhcp6.client_id, child->cdata)) return -1; } else if (ni_string_eq(child->name, "server-id") && child->cdata) { if (!ni_duid_parse_hex(&lease->dhcp6.server_id, child->cdata)) return -1; } else if (ni_string_eq(child->name, "server-address") && child->cdata) { if (ni_sockaddr_parse(&addr, child->cdata, AF_INET6) < 0) return -1; lease->dhcp6.server_addr = addr.six.sin6_addr; } else if (ni_string_eq(child->name, "server-preference") && child->cdata) { if (ni_parse_uint(child->cdata, &value, 10) != 0 || value > 255) return -1; lease->dhcp6.server_pref = value; } else if (ni_string_eq(child->name, "rapid-commit")) { lease->dhcp6.rapid_commit = TRUE; } else if (ni_string_eq(child->name, "hostname") && child->cdata) { ni_string_dup(&lease->hostname, child->cdata); } if (ni_string_eq(child->name, ia_na_name)) { if (__ni_dhcp6_lease_ia_type_from_xml(&lease->dhcp6.ia_list, NI_DHCP6_OPTION_IA_NA, child) < 0) return -1; } else if (ni_string_eq(child->name, ia_ta_name)) { if (__ni_dhcp6_lease_ia_type_from_xml(&lease->dhcp6.ia_list, NI_DHCP6_OPTION_IA_TA, child) < 0) return -1; } else if (ni_string_eq(child->name, ia_pd_name)) { if (__ni_dhcp6_lease_ia_type_from_xml(&lease->dhcp6.ia_list, NI_DHCP6_OPTION_IA_PD, child) < 0) return -1; } else if (ni_string_eq(child->name, "boot")) { if (__ni_dhcp6_lease_boot_from_xml(lease, child) < 0) return -1; } else if (ni_string_eq(child->name, NI_ADDRCONF_LEASE_XML_DNS_DATA_NODE)) { if (ni_addrconf_lease_dns_data_from_xml(lease, child, ifname) < 0) return -1; } else if (ni_string_eq(child->name, NI_ADDRCONF_LEASE_XML_NTP_DATA_NODE)) { if (ni_addrconf_lease_ntp_data_from_xml(lease, child, ifname) < 0) return -1; } else if (ni_string_eq(child->name, NI_ADDRCONF_LEASE_XML_SIP_DATA_NODE)) { if (ni_addrconf_lease_sip_data_from_xml(lease, child, ifname) < 0) return -1; } else if (ni_string_eq(child->name, NI_ADDRCONF_LEASE_XML_PTZ_DATA_NODE)) { if (ni_addrconf_lease_ptz_data_from_xml(lease, child, ifname) < 0) return -1; } else if (ni_string_eq(child->name, NI_ADDRCONF_LEASE_XML_OPTS_DATA_NODE)) { if (ni_addrconf_lease_opts_data_from_xml(lease, child, ifname) < 0) return -1; } } return 0; }
static int ni_do_duid_set(int argc, char **argv) { enum { OPT_HELP = 'h', OPT_SCOPE = 's' }; static struct option options[] = { { "help", no_argument, NULL, OPT_HELP }, { "scope", required_argument, NULL, OPT_SCOPE }, { NULL, no_argument, NULL, 0 } }; int opt = 0, status = NI_WICKED_RC_USAGE; ni_duid_map_t *map = NULL; const char *scope = NULL; const char *duid = NULL; ni_opaque_t raw; optind = 1; while ((opt = getopt_long(argc, argv, "+hs:", options, NULL)) != EOF) { switch (opt) { case OPT_SCOPE: if (optarg && !ni_string_eq(optarg, "default")) scope = optarg; break; case OPT_HELP: status = NI_WICKED_RC_SUCCESS; default: usage: fprintf(stderr, "Usage: %s [options] <duid>\n" "\n" "Options:\n" " --help, -h show this help text and exit.\n" " --scope <ifname> set device specific duid instead of default\n" "\n" "Arguments:\n" " duid duid string as colon-separated hex bytes\n" "\n", argv[0]); goto cleanup; } } switch (argc - optind) { case 1: duid = argv[optind++]; break; default: goto usage; } if (scope && !ni_netdev_name_is_valid(scope)) { fprintf(stderr, "%s: invalid scope interface name '%s'\n", argv[0], ni_print_suspect(scope, ni_string_len(scope))); status = NI_WICKED_RC_ERROR; goto cleanup; } if (ni_string_empty(duid) || !ni_duid_parse_hex(&raw, duid)) { fprintf(stderr, "%s: unable to parse duid hex string argument\n", argv[0]); status = NI_WICKED_RC_ERROR; goto cleanup; } status = NI_WICKED_RC_ERROR; if (!(map = ni_duid_map_load(NULL))) goto cleanup; if (!ni_duid_map_set(map, scope, duid)) goto cleanup; if (!ni_duid_map_save(map)) goto cleanup; status = NI_WICKED_RC_SUCCESS; cleanup: ni_duid_map_free(map); return status; }