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

📄 dhcps.c

📁 vxworks下dhcpc,dhcpr,dhcps库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
* get_cid - Retrieve client identifier** This routine extracts the client identifier from the options field of the* DHCP client request and stores the <type>:<value> pair in the given * structure. If no explicit client ID is given, the routine uses the hardware* address, as specified by RFC 1541.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static void get_cid (struct dhcp *msg,  /* pointer to incoming message */                     int length,    /* length of incoming message */                     struct client_id *cid  /* pointer to storage for parsed data */    ){    char *option = NULL;    option = pickup_opt (msg, length, _DHCP_CLIENT_ID_TAG);    if (option != NULL) {        cid->idlen = ((int) DHCPOPTLEN (option)) - 1;   /* -1 for ID type */        bcopy (OPTBODY (option) + 1, cid->id, cid->idlen);        cid->idtype = *OPTBODY (option);    } else {        /* haddr is used to substitute for client identifier */        cid->idlen = msg->hlen;        cid->idtype = msg->htype;        bcopy (msg->chaddr, cid->id, msg->hlen);    }    return;}/********************************************************************************* get_maxoptlen - Calculate size of options field** This routine determines the number of bytes available for DHCP options* without overloading. For standard length messages of 548 bytes, it returns * the default length of 312 bytes. For longer messages, it returns 312 bytes * plus the excess bytes (beyond 548), unless the DHCP message length exceeds* the MTU size. In that case, it returns the number of bytes in the MTU not* needed for the IP header, UDP header, and the fixed-length portion of the* DHCP messages, which require 264 bytes total.** RETURNS: Size of variable-length options field** ERRNO: N/A** NOMANUAL*/static int get_maxoptlen (struct dhcp *msg, /* pointer to incoming message */                          int length    /* length of incoming message */    ){    char *option = NULL;    int retval = DFLTOPTLEN;    /* Calculate length of options field from maximum message size. */    if ((option = pickup_opt (msg, length, _DHCP_MAXMSGSIZE_TAG)) != NULL)        retval = GETHS (OPTBODY (option)) - IPHL - UDPHL - DFLTDHCPLEN + DFLTOPTLEN;    /*      * If requested maximum size exceeds largest supported value, return     * value equal to portion of buffer not required for message headers     * or fixed-size portion of DHCP message.      */    if (retval - DFLTOPTLEN + DFLTDHCPLEN + UDPHL + IPHL > dhcpsMaxSize)        retval = dhcpsMaxSize - IPHL - UDPHL - DFLTDHCPLEN + DFLTOPTLEN;    return (retval);}/********************************************************************************* get_subnet - Retrieve subnet number** This routine determines the subnet number of the requesting client and* stores it in the given structure. This value is determined using the* subnet mask specified by the client, if present. Otherwise, it is formed* from the last known subnet mask, if available, or the subnet mask of the* receiving interface. The server will only issue leases for IP addresses * with the same subnet number as the requesting client.** RETURNS: 0 if subnet number determined, or -1 otherwise.** ERRNO: N/A** NOMANUAL*/static int get_subnet (struct dhcp *msg,    /* pointer to incoming message */                       int length,  /* length of incoming message */                       struct in_addr *subn,    /* pointer to storage for parsed data */                       struct if_info *ifp  /* pointer to receiving interface descriptor */    ){    char *option = NULL;    struct relay_acl *acl = NULL;    struct dhcp_resource *res = NULL;#ifdef DHCPS_DEBUG    char output[INET_ADDR_LEN];#endif    if (msg->ciaddr.s_addr != 0) {        if ((option = pickup_opt (msg, length, _DHCP_SUBNET_MASK_TAG))            != NULL) {            subn->s_addr = msg->ciaddr.s_addr & htonl (GETHL (OPTBODY (option)));            return (0);        } else {            res = (struct dhcp_resource *)                hash_find (&iphashtable, (char *) &msg->ciaddr.s_addr,                           sizeof (u_long), resipcmp, &msg->ciaddr);#ifdef DHCPS_DEBUG            if (res == NULL)                logMsg ("get_subnet can't find IP address in hash table.\n", 0, 0, 0, 0, 0, 0);#endif            if (res != NULL) {                subn->s_addr = msg->ciaddr.s_addr & res->subnet_mask.s_addr;                return (0);            }        }    }    if (msg->giaddr.s_addr != 0) {        if ((option = pickup_opt (msg, length, _DHCP_SUBNET_MASK_TAG))            != NULL) {            subn->s_addr = msg->giaddr.s_addr & htonl (GETHL (OPTBODY (option)));            return (0);        } else if ((acl = (struct relay_acl *)                    hash_find (&relayhashtable, (char *) &msg->giaddr,                               sizeof (struct in_addr), relayipcmp, &msg->giaddr)) == NULL) {#ifdef DHCPS_DEBUG            inet_ntoa_b (msg->giaddr, output);            logMsg ("DHCP message sent from invalid relay agent(%s).\n", output, 0, 0, 0, 0, 0);#endif            return (-1);        } else {            subn->s_addr = (acl->relay.s_addr & acl->subnet_mask.s_addr);            return (0);        }    }    /* Client doesn't have IP address - form from received interface. */    subn->s_addr = ifp->ipaddr.s_addr & ifp->subnetmask.s_addr;    return (0);}/********************************************************************************* get_snmk - Retrieve subnet mask** This routine determines the subnet mask for the requesting client and* stores it in the given structure. This value is determined from the * value specified for the relay agent, if the message was forwarded, or* the subnet mask of the receiving interface. ** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static int get_snmk (struct dhcp *msg,  /* pointer to incoming message */                     int length,    /* length of incoming message */                     struct in_addr *subn,  /* pointer to storage for parsed data */                     struct if_info *ifp    /* pointer to interface descriptor */    ){    struct relay_acl *acl = NULL;#ifdef DHCPS_DEBUG    char output[INET_ADDR_LEN];#endif    if (msg->giaddr.s_addr != 0) {        acl = (struct relay_acl *) hash_find (&relayhashtable,                                              (char *) &msg->giaddr,                                              sizeof (struct in_addr), relayipcmp, &msg->giaddr);        if (acl == NULL) {#ifdef DHCPS_DEBUG            inet_ntoa_b (msg->giaddr, output);            logMsg ("packet received from invalid relay agent(%s).\n", output, 0, 0, 0, 0, 0);#endif            return (-1);        } else {            subn->s_addr = acl->subnet_mask.s_addr;            return (0);        }    }    subn->s_addr = ifp->subnetmask.s_addr;    return (0);}/********************************************************************************* available_res - Check resource availability** This routine determines if the resource selected by the server may* be offered to the client. The resource is available if it has not been* assigned or offered to any client (res->binding == NULL), or the lease has * expired (expire_epoch < curr_epoch), or an outstanding offer was not * acknowledged within the time allotted (temp_epoch < curr_epoch). The* resource is also available if it was  manually assigned to the given * client (binding->cid matches given client ID).** RETURNS: TRUE if resource available, or FALSE otherwise. ** ERRNO: N/A** NOMANUAL*/static int available_res (struct dhcp_resource *res,    /* pointer to lease descriptor */                          struct client_id *cid,    /* pointer to client ID */                          time_t curr_epoch /* current time, in seconds */    ){    return (res->binding == NULL ||            (res->binding->expire_epoch != 0xffffffff &&             res->binding->expire_epoch < curr_epoch &&             res->binding->temp_epoch < curr_epoch) || cidcmp (&res->binding->cid, cid));}/********************************************************************************* cidcopy - copy client identifier** This routine copies the <type>:<value> client identifier pair from the* source structure to the destination.** RETURNS: 0, always.** ERRNO: N/A** NOMANUAL*/static int cidcopy (struct client_id *src,  /* source client identifier */                    struct client_id *dst   /* destiniation client identifier */    ){    dst->subnet.s_addr = src->subnet.s_addr;    dst->idtype = src->idtype;    dst->idlen = src->idlen;    bzero (dst->id, src->idlen);    bcopy (src->id, dst->id, src->idlen);    return (0);}/********************************************************************************* choose_lease - determine lease duration** This routine selects the lease duration for the offer to the client. If* the resource is client-specific, the lease duration is infinite. Otherwise,* the server provides the duration requested by the client, if available, or * the maximum available lease, whichever is less. If the client does not * request a lease duration, and has no active lease, the default lease value * is returned. For lease renewals or rebinding attempts, or if the lease* has expired, the default lease value is also returned.** RETURNS: Selected lease duration.** ERRNO: N/A** NOMANUAL*/static int choose_lease (int reqlease,  /* requested lease duration (sec) */                         time_t curr_epoch, /* current time, in seconds */                         struct dhcp_resource *offer_res    /* pointer to lease descriptor */    ){    u_long offer_lease = 0;    /* Manual allocation - give an infinite lease to client. */    if (ISSET (offer_res->valid, S_CLIENT_ID))        offer_lease = 0xffffffff;    /* Give requested lease, or maximum lease if request exceeds that value. */    else if (reqlease != 0) {        if (reqlease <= offer_res->max_lease)            offer_lease = reqlease;        else            offer_lease = offer_res->max_lease;    }    /* Initial request - give default lease. */    else if (offer_res->binding == NULL)        offer_lease = offer_res->default_lease;    /* Lease renewal or rebinding. */    else {        /* "Renew" infinite lease. */        if (offer_res->binding->expire_epoch == 0xffffffff)            offer_lease = 0xffffffff;        /*         * Lease expired (or being renewed) - give new lease         * of default duration.         */        else            offer_lease = offer_res->default_lease;    }    return (offer_lease);}/********************************************************************************* select_wcid - retrieve manually allocated leases** This routine retrieves the dhcp_resource structure which holds the parameters* from the address pool database specifically allocated to the client with* the given client identifier, if any. These lease types have the highest* priority when the server is selecting a lease for a client in response to* a DHCP discover message.** RETURNS: Manually allocated resource, or NULL if none or not available.** ERRNO: N/A** NOMANUAL*/static struct dhcp_resource *select_wcid (int msgtype,  /* DHCP message type */                                          struct client_id *cid,    /* pointer to client ID */                                          time_t curr_epoch /* current time, in seconds */    ){    struct dhcp_binding *binding = NULL;    binding = (struct dhcp_binding *) hash_find (&cidhashtable, cid->id,                                                 cid->idlen, bindcidcmp, cid);    if (binding != NULL) {        /*         * Is the resource used ?         */        if (available_res (binding->res, cid, curr_epoch)) {            if (icmp_check (msgtype, &binding->res->ip_addr) == GOOD) {                return (binding->res);            } else {                turnoff_bind (binding);                return (NULL);            }        }    }    return (NULL);}/********************************************************************************* select_wreqip - retrieve resource matching IP address** This routine retrieves the dhcp_resource structure which provides the IP

⌨️ 快捷键说明

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