void configure_commit(void) { struct dhcp6_ifconf *ifc; struct dhcp6_if *ifp; /* commit interface configuration */ for (ifc = dhcp6_ifconflist; ifc; ifc = ifc->next) { if ((ifp = find_ifconfbyname(ifc->ifname)) != NULL) { ifp->send_flags = ifc->send_flags; ifp->allow_flags = ifc->allow_flags; dhcp6_clear_list(&ifp->reqopt_list); ifp->reqopt_list = ifc->reqopt_list; TAILQ_INIT(&ifc->reqopt_list); dhcp6_clear_list(&ifp->addr_list); ifp->addr_list = ifc->addr_list; TAILQ_INIT(&ifc->addr_list); dhcp6_clear_list(&ifp->prefix_list); ifp->prefix_list = ifc->prefix_list; TAILQ_INIT(&ifc->prefix_list); clear_option_list(&ifp->option_list); ifp->option_list = ifc->option_list; TAILQ_INIT(&ifc->option_list); ifp->server_pref = ifc->server_pref; /* Foxconn added start pling 09/07/2010 */ /* configure user-class */ if (dhcp6_mode == DHCP6_MODE_CLIENT) strcpy(ifp->user_class, ifc->user_class); /* Foxconn added end pling 09/07/2010 */ memcpy(&ifp->iaidinfo, &ifc->iaidinfo, sizeof(ifp->iaidinfo)); } } clear_ifconf(dhcp6_ifconflist); /* commit prefix configuration */ if (host_conflist) { /* clear previous configuration. (need more work?) */ clear_hostconf(host_conflist); } host_conflist = host_conflist0; host_conflist0 = NULL; }
void configure_cleanup(void) { clear_ifconf(dhcp6_ifconflist); dhcp6_ifconflist = NULL; clear_hostconf(host_conflist0); host_conflist0 = NULL; dhcp6_clear_list(&dnslist0); TAILQ_INIT(&dnslist0); }
static void clear_ifconf(struct dhcp6_ifconf *iflist) { struct dhcp6_ifconf *ifc, *ifc_next; for (ifc = iflist; ifc; ifc = ifc_next) { ifc_next = ifc->next; free(ifc->ifname); dhcp6_clear_list(&ifc->reqopt_list); free(ifc); } }
int dhcp6_copy_list(struct dhcp6_list *dst, const struct dhcp6_list *src) { const struct dhcp6_listval *ent; struct dhcp6_listval *dent; for (ent = TAILQ_FIRST(src); ent; ent = TAILQ_NEXT(ent, link)) { if ((dent = malloc(sizeof(*dent))) == NULL) goto fail; memset(dent, 0, sizeof(*dent)); memcpy(&dent->uv, &ent->uv, sizeof(ent->uv)); TAILQ_INSERT_TAIL(dst, dent, link); } return 0; fail: dhcp6_clear_list(dst); return -1; }
int dad_parse(const char *file, struct dhcp6_list *dad_list) { int i = 0; int len = 0; int ret = 0; FILE *fp = NULL; char buf[55]; /* max line length in /proc/net/if_inet6 */ char addrbuf[64]; char *tmp = NULL; struct in6_addr addr6; struct ifproc_info *ifinfo = NULL; if (file == NULL) { dhcpv6_dprintf(LOG_ERR, "dad_parse: NULL filename"); return -1; } memset(&buf, '\0', sizeof(buf)); memset(&addr6, 0, sizeof(addr6)); if ((fp = fopen(file, "r")) == NULL) { if (errno == ENOENT) { return 0; } dhcpv6_dprintf(LOG_ERR, "dad_parse: fopen(%s): %s", file, strerror(errno)); return -1; } while (fgets(buf, sizeof(buf), fp) != NULL) { /* read address */ if ((tmp = strtok(buf, " \n")) == NULL) { continue; } len = 0; for (i = 0; i < 32; i += 4) { strncpy(addrbuf + len, &tmp[i], 4); len += 4; if (i < 28) { strcpy(addrbuf + len, ":"); len += 1; } else { strcpy(addrbuf + len, "\0"); } } if (inet_pton(AF_INET6, addrbuf, &addr6) < 1) { dhcpv6_dprintf(LOG_ERR, "failed to parse %s from %s", addrbuf, file); abort(); } if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) { dhcpv6_dprintf(LOG_ERR, "memory allocation failure"); abort(); } memcpy(&ifinfo->addr, &addr6, sizeof(ifinfo->addr)); /* read the index */ if ((tmp = strtok(NULL, " \n")) == NULL) { continue; } ifinfo->index = strtol(tmp, NULL, 16); if ((errno == EINVAL) || (errno == ERANGE)) { dhcpv6_dprintf(LOG_ERR, "error reading index from %s", file); goto fail; } /* read the prefix length */ if ((tmp = strtok(NULL, " \n")) == NULL) { continue; } ifinfo->plen = strtol(tmp, NULL, 16); if ((errno == EINVAL) || (errno == ERANGE)) { dhcpv6_dprintf(LOG_ERR, "error reading prefix length from %s", file); goto fail; } /* read the scope */ if ((tmp = strtok(NULL, " \n")) == NULL) { continue; } ifinfo->scope = strtol(tmp, NULL, 16); if ((errno == EINVAL) || (errno == ERANGE)) { dhcpv6_dprintf(LOG_ERR, "error reading scope from %s", file); goto fail; } /* read the flags */ if ((tmp = strtok(NULL, " \n")) == NULL) { continue; } ifinfo->flags = strtol(tmp, NULL, 16); if ((errno == EINVAL) || (errno == ERANGE)) { dhcpv6_dprintf(LOG_ERR, "error reading flags from %s", file); goto fail; } if (ifinfo->flags == DAD_FLAGS) { dhcpv6_dprintf(LOG_INFO, "duplicated IPv6 address %s detected", in6addr2str(&ifinfo->addr, 0)); } else { free(ifinfo); ifinfo = NULL; continue; } /* read the interface name */ if ((tmp = strtok(NULL, " \n")) == NULL) { continue; } if (strcmp(tmp, dhcp6_if->ifname)) { free(ifinfo); ifinfo = NULL; continue; } else { struct dhcp6_listval *lv; strncpy(ifinfo->name, tmp, IF_NAMESIZE); ifinfo->next = NULL; /* check address on client6_iaidaddr list */ if ((lv = malloc(sizeof(*lv))) == NULL) { dhcpv6_dprintf(LOG_ERR, "memory allocation failure"); abort(); } memcpy(&lv->val_dhcp6addr.addr, &ifinfo->addr, sizeof(lv->val_dhcp6addr.addr)); lv->val_dhcp6addr.type = IANA; lv->val_dhcp6addr.plen = ifinfo->plen; lv->val_dhcp6addr.status_code = DH6OPT_STCODE_UNDEFINE; lv->val_dhcp6addr.preferlifetime = 0; lv->val_dhcp6addr.validlifetime = 0; TAILQ_INSERT_TAIL(dad_list, lv, link); } } out: if (fclose(fp) == EOF) { fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); fflush(stderr); abort(); } return ret; fail: dhcp6_clear_list(dad_list); ret = -1; goto out; }