⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcps.c

📁 vxworks下dhcpc,dhcpr,dhcps库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
* address requested by the client. The requested IP address must be on the* same subnet as the requesting client. The client must also provide a* matching client identifier, if included in the server's database entry.** RETURNS: Matching resource, or NULL if none or not available.** ERRNO: N/A** NOMANUAL*/static struct dhcp_resource *select_wreqip (int msgtype,    /* DHCP message type */                                            struct client_id *cid,  /* pointer to client ID */                                            time_t curr_epoch   /* current time, in seconds */    ){    char *option = NULL;        /* pointer to access options field */    char tmp[INET_ADDR_LEN];    /* temp IP address storage */    struct dhcp_resource *res = NULL;   /* access to lease descriptor data */    struct in_addr reqip;       /* value of desired IP address */    bzero (tmp, sizeof (tmp));    bzero ((char *) &reqip, sizeof (reqip));    option = pickup_opt (dhcpsMsgIn.dhcp, rdhcplen, _DHCP_REQUEST_IPADDR_TAG);    if (option != NULL) {        reqip.s_addr = htonl (GETHL (OPTBODY (option)));        res = (struct dhcp_resource *) hash_find (&iphashtable,                                                  (char *) &reqip.s_addr,                                                  sizeof (u_long), resipcmp, &reqip);        if (res == NULL) {#ifdef DHCPS_DEBUG            inet_ntoa_b (reqip, tmp);            logMsg ("IP address %s is not in address pool", tmp, 0, 0, 0, 0, 0);#endif            return (NULL);        } else {            /* check the subnet number */            if (cid->subnet.s_addr != (res->ip_addr.s_addr & res->subnet_mask.s_addr)) {#ifdef DHCPS_DEBUG                inet_ntoa_b (reqip, tmp);                logMsg ("DHCP%s(cid:\"%s\"): subnet mismatch for requested IP address %s.\n",                        (int) ((msgtype == DHCPDISCOVER) ? "DISCOVER" : "REQUEST"),                        (int) cidtos (cid, 1), (int) tmp, 0, 0, 0);#endif                return (NULL);            }            /* is it manual allocation ? */            if (ISSET (res->valid, S_CLIENT_ID)) {                /* is there corresponding binding ? */                if (res->binding == NULL) {#ifdef DHCPS_DEBUG                    inet_ntoa_b (reqip, tmp);                    logMsg ("DHCP%s(cid:\"%s\"): No corresponding binding for %s",                            (int) ((msgtype == DHCPDISCOVER) ? "DISCOVER" : "REQUEST"),                            (int) cidtos (cid, 1), (int) tmp, 0, 0, 0);#endif                    return (NULL);                }                /* Check for matching client identifiers. */                if (cidcmp (&res->binding->cid, cid) != TRUE) {#ifdef DHCPS_DEBUG                    inet_ntoa_b (reqip, tmp);                    logMsg ("DHCP%s(cid:\"%s\"): Client ID mismatch for requested IP address %s.\n",                            (int) ((msgtype == DHCPDISCOVER) ? "DISCOVER" : "REQUEST"),                            (int) cidtos (cid, 1), (int) tmp, 0, 0, 0);#endif                    return (NULL);                }                /* Check if the address is already in use. */                if (icmp_check (msgtype, &res->ip_addr) == GOOD)                    return (res);                else {                    turnoff_bind (res->binding);                    return (NULL);                }            }            /* If not manual allocation, is the requested lease available? */            else if (available_res (res, cid, curr_epoch)) {                if (icmp_check (msgtype, &res->ip_addr) == GOOD)                    return (res);                else {                    turnoff_bind (res->binding);                    return (NULL);                }            }        }    }    return (NULL);              /* No requested IP address present in option list. */}/********************************************************************************* select_newone - choose an entry from the available resources** This routine retrieves a dhcp_resource structure for a client if no entry* was found based on the requested IP address, if any, or the client * identifier. No addresses which are in use or on a different subnet than * the client are considered. For the remaining entries, it uses the following * criteria:**      First, select entries which were never used in preference to used ones.**      If not found, select the least recently used entry.**      Next, give preference to entries which are unavailable to BOOTP clients.**      Among unused or equally old entries, select the smallest possible *      maximum which exceeds the requested lease length. If not found, *      choose the resource with the largest maximum lease length.**      The previous condition excludes resources with an infinite maximum*      lease whenever possible, unless specifically requested by the client.**      If not found (i.e. - all entries have same maximum lease length), *      select the first available entry in the database.** RETURNS: Matching resource, or NULL if none or not available.** ERRNO: N/A** NOMANUAL*/static struct dhcp_resource *select_newone (int msgtype,    /* DHCP message type */                                            struct client_id *cid,  /* pointer to client ID */                                            time_t curr_epoch,  /* current time, in seconds */                                            u_long reqlease /* requested lease duration (seconds) */    ){    struct dhcp_resource *res = NULL;    struct dhcp_resource *best = NULL;    struct hash_member *resptr = NULL;    /* Examine each resource in list constructed from database. */    resptr = reslist;    while (resptr != NULL) {        res = (struct dhcp_resource *) resptr->data;        if (res->ip_addr.s_addr == 0) { /* Skip dummy entries. */            resptr = resptr->next;            continue;        }        /*         * Check the resource subnet and availability. Skip entries which          * are not available or would change the subnet of the client.         */        if (cid->subnet.s_addr ==            (res->ip_addr.s_addr & res->subnet_mask.s_addr) &&            available_res (res, cid, curr_epoch)) {            /*             * choose the best entry from available resources on the same              * subnet. The criteria are listed in inverse priority order.             */            /* Lowest priority - take first available entry. */            if (best == NULL) {                if (icmp_check (msgtype, &res->ip_addr) == GOOD)                    best = res;                else                    turnoff_bind (res->binding);                resptr = resptr->next;                continue;            }            /* Select unused entries in preference to used ones. */            if (best->binding == NULL && res->binding != NULL) {                resptr = resptr->next;                continue;            } else if (best->binding != NULL && res->binding == NULL) {                if (icmp_check (msgtype, &res->ip_addr) == GOOD)                    best = res;                else                    turnoff_bind (res->binding);                resptr = resptr->next;                continue;            }            /* Give preference to entries not available to BOOTP clients. */            if (best->allow_bootp == FALSE && res->allow_bootp == TRUE) {                resptr = resptr->next;                continue;            } else if (best->allow_bootp == TRUE && res->allow_bootp == FALSE) {                if (icmp_check (msgtype, &res->ip_addr) == GOOD)                    best = res;                else                    turnoff_bind (res->binding);                resptr = resptr->next;                continue;            }            /*             * Tiebreaker conditionals for preferred entries (either both              * unused or which both qualify as least recently used).              * Overall, these conditionals select the resource whose maximum             * lease exceeds the threshold of the requested lease length by              * the minimum amount. If there is no resource whose maximum lease             * exceeds the requested lease length, the resource with the             * largest maximum lease is chosen.             *             * NOTE: These conditionals also implement a preference for resource             *       entries which do not provide an infinite lease, unless             *       specifically requested by the client.             */            if ((best->binding == NULL && res->binding == NULL) ||                (best->binding != NULL && res->binding != NULL &&                 best->binding->expire_epoch == res->binding->expire_epoch)) {                /*                 * Select resource with larger maximum lease,                 * even if shorter than the requested lease length.                 * Combined with the third conditional, the maximum value                 * of the maximum lease will be selected, if the lease length                 * threshold is not exceeded.                 */                if (reqlease >= res->max_lease && res->max_lease > best->max_lease) {                    if (icmp_check (msgtype, &res->ip_addr) == GOOD)                        best = res;                    else                        turnoff_bind (res->binding);                    resptr = resptr->next;                    continue;                }                /*                 * Among resources whose maximum lease exceeds                 * the requested value, select the minimum.                 * This condition is never true until either the                  * previous or next condition evaluated to true.                 */                if (reqlease != INFINITY && reqlease <= res->max_lease &&                    res->max_lease < best->max_lease) {                    if (icmp_check (msgtype, &res->ip_addr) == GOOD)                        best = res;                    else                        turnoff_bind (res->binding);                    resptr = resptr->next;                    continue;                }                /*                 * Accept entries longer than both the requested value                  * and the current maximum. This condition evaluates to                 * true at most once. Once it does, neither it or the                 * first conditional will ever evaluate to true again.                 */                if (reqlease != INFINITY && res->max_lease >= reqlease &&                    reqlease > best->max_lease) {                    if (icmp_check (msgtype, &res->ip_addr) == GOOD)                        best = res;                    else                        turnoff_bind (res->binding);                    resptr = resptr->next;                    continue;                }                resptr = resptr->next;                continue;            }            /*             * Among previously used entries, select those which expired              * earlier. (In the aggregate, implements a LRU algorithm).             */            if (best->binding != NULL && res->binding != NULL &&                best->binding->expire_epoch > res->binding->expire_epoch) {                if (icmp_check (msgtype, &res->ip_addr) == GOOD)                    best = res;                else                    turnoff_bind (res->binding);                resptr = resptr->next;                continue;            } else {                resptr = resptr->next;                continue;            }        }        resptr = resptr->next;    }    return (best);}/********************************************************************************* choose_res - select a resource for DHCP client** This routine chooses a resource in response to an incoming DHCP discover * message. If the server database contains a manual entry matching the* client identifier, the corresponding resource is returned. Otherwise,* the database entry which provides the requested IP address, if any, is * chosen. If the discover message does not require a specific entry, the* server selects a new entry using its own internal criteria, or NULL if* no entry is available.** RETURNS: Matching resource, or NULL if none available.** ERRNO: N/A** NOMANUAL*/static struct dhcp_resource *choose_res (struct client_id *cid, /* pointer to client ID */                                         time_t curr_epoch, /* current time, in seconds */                                         u_long reqlease    /* requested lease duration (seconds) */    ){    struct dhcp_resource *res = NULL;    /* 1. select with client identifier, if  found. */    if ((res = select_wcid (DHCPDISCOVER, cid, curr_epoch)) != NULL)        return (res);    /* 2. select with requested IP address, if any. */    if ((res = select_wreqip (DHCPDISCOVER, cid, curr_epoch)) != NULL)        return (res);    /* 3. select an entry using internal criteria. */    res = select_newone (DHCPDISCOVER, cid, curr_epoch, reqlease);    if (res != NULL)        return (res);#ifdef DHCPS_DEBUG    logMsg ("Warning: DHCPDISCOVER - No available addresses in the pool.\n", 0, 0, 0, 0, 0, 0);#endif    return (NULL);}/********************************************************************************* update_db - add entries to internal data structures to reflect client state** This routine updates the binding list and corresponding hash tables when* the server receives a DHCP discover message, or a DHCP or BOOTP request* message from a client. The binding entry for the resource is marked* unavailable for a short interval (for DHCP discover) or until the expiration* of the lease.** RETURNS: 0 if update completed, or -1 on error.** ERRNO: N/A** NOMANUAL*/static int update_db (int msgtype,  /* DHCP message type */                      struct client_id *cid,    /* pointer to client ID */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -