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 ifinit(const char *ifname) { struct dhcp6_if *ifp; if ((ifp = find_ifconfbyname(ifname)) != NULL) { dprintf(LOG_NOTICE, "%s" "duplicated interface: %s", FNAME, ifname); return; } if ((ifp = malloc(sizeof(*ifp))) == NULL) { dprintf(LOG_ERR, "%s" "malloc failed", FNAME); goto die; } memset(ifp, 0, sizeof(*ifp)); TAILQ_INIT(&ifp->event_list); if ((ifp->ifname = strdup(ifname)) == NULL) { dprintf(LOG_ERR, "%s" "failed to copy ifname", FNAME); goto die; } if ((ifp->ifid = if_nametoindex(ifname)) == 0) { dprintf(LOG_ERR, "%s" "invalid interface(%s): %s", FNAME, ifname, strerror(errno)); goto die; } #ifdef HAVE_SCOPELIB if (inet_zoneid(AF_INET6, 2, ifname, &ifp->linkid)) { dprintf(LOG_ERR, "%s" "failed to get link ID for %s", FNAME, ifname); goto die; } #else ifp->linkid = ifp->ifid; /* XXX */ #endif if (get_linklocal(ifname, &ifp->linklocal) < 0) goto die; ifp->next = dhcp6_if; dhcp6_if = ifp; return; die: exit(1); }
int netlink_recv( int fd, struct dhcp6_if **pp_if) { int status; struct msghdr msg; struct sockaddr_nl dest_addr; struct nlmsghdr *nlh; struct iovec iov; struct dad_failed_msg_t *dad_msg; nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(sizeof(struct dad_failed_msg_t))); if (!nlh) { dprintf(LOG_INFO, FNAME, "malloc failed\n"); return 2; } memset(nlh, 0, NLMSG_SPACE(sizeof(struct dad_failed_msg_t))); iov.iov_base = (void *)nlh; iov.iov_len = NLMSG_SPACE(sizeof(struct dad_failed_msg_t)); msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; dprintf(LOG_INFO, FNAME, "Starting recv,iov length is %d",(int)iov.iov_len); status = recvmsg(fd, &msg, 0); if (status < 0) { // close(fd); free(nlh); dprintf(LOG_INFO, FNAME, "recvmsg failed, error: %s", strerror(errno) ); return 1; } if (iov.iov_len == nlh->nlmsg_len) { dad_msg = (struct dad_failed_msg_t *)NLMSG_DATA(nlh); #define ADDR_PREFIX_FMT "%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X/%d" #define ADDR_PREFIX_PARAM(dad_msg) dad_msg->addr.s6_addr16[0],\ dad_msg->addr.s6_addr16[1],\ dad_msg->addr.s6_addr16[2],\ dad_msg->addr.s6_addr16[3],\ dad_msg->addr.s6_addr16[4],\ dad_msg->addr.s6_addr16[5],\ dad_msg->addr.s6_addr16[6],\ dad_msg->addr.s6_addr16[7],\ dad_msg->prefix_len dprintf(LOG_INFO, FNAME, "DAD failed on interface %s,Address:" ADDR_PREFIX_FMT, dad_msg->name, ADDR_PREFIX_PARAM(dad_msg)); } free(nlh); // close(fd); struct dhcp6_if *ifp = NULL; if ((ifp = find_ifconfbyname(dad_msg->name)) == NULL) { dprintf(LOG_INFO, FNAME, "failed to find interface configuration for %s", dad_msg->name); return 11; } // returned value memcpy( &(ifp->addr.s6_addr32), &(dad_msg->addr.s6_addr32), sizeof( struct in6_addr ) ); *pp_if = ifp; dprintf(LOG_INFO, FNAME, "Then we should send DH6_DECLINE to: %s", ifp->ifname ); return 0; }