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

📄 dhcps.c

📁 VXWORKS下的DHCP源程序
💻 C
📖 第 1 页 / 共 5 页
字号:
                           == E_NOMORE)                        {#ifdef DHCPS_DEBUG                        logMsg ("No space left in options field for DHCP%s",                               (int)((msgtype == DHCPOFFER) ? "OFFER" : "ACK"),                               0, 0, 0, 0, 0);#endif                        break;                        }            tmp = 1;       /* Client-specific options found. */            }        }    /*     * If no client ID included, or no associated options found, check      * hardware address.      */    if (tmp == 0)        {        paramId.idlen = dhcpsMsgIn.dhcp->hlen;        paramId.idtype = dhcpsMsgIn.dhcp->htype;        bcopy (dhcpsMsgIn.dhcp->chaddr, paramId.id, dhcpsMsgIn.dhcp->hlen);        params = hash_find (&paramhashtable,                            paramId.id, paramId.idlen, paramcidcmp, &paramId);        /* Insert options from matching resource entry not already present. */        if (params != NULL)            {            for (i = 0; i < _DHCP_LAST_OPTION; i++)                if (ISCLR (inserted, i))                    if (insert_opt (params, lease, i, inserted, PASSIVE)                           == E_NOMORE)                        {#ifdef DHCPS_DEBUG                        logMsg ("No space left in options field for DHCP%s",                               (int)((msgtype == DHCPOFFER) ? "OFFER" : "ACK"),                               0, 0, 0, 0, 0);#endif                        break;                        }            }        }    /* Insert any class-specific options. */    option = pickup_opt (dhcpsMsgIn.dhcp, rdhcplen, _DHCP_CLASS_ID_TAG);    if (option != NULL)        {        paramId.idlen = DHCPOPTLEN (option);        paramId.idtype = 0;         /* Unused for class identifiers. */        bcopy (OPTBODY (option), paramId.id, paramId.idlen);        params = hash_find (&paramhashtable,                            paramId.id, paramId.idlen, paramcidcmp, &paramId);        /* Insert options from matching resource entry not already present. */        if (params != NULL)            {            for (i = 0; i < _DHCP_LAST_OPTION; i++)                if (ISCLR (inserted, i))                    if (insert_opt (params, lease, i, inserted, PASSIVE)                           == E_NOMORE)                        {#ifdef DHCPS_DEBUG                        logMsg ("No space left in options field for DHCP%s",                               (int)((msgtype == DHCPOFFER) ? "OFFER" : "ACK"),                               0, 0, 0, 0, 0);#endif                        break;                        }            }        }    return;    }/********************************************************************************* select_wciaddr - retrieve resource with matching IP address** This routine attempts to find an address pool entry whose IP address matches* the value requested by the client. If the matching IP address is part of a* manual lease, it also verifies that the client ID matches the required value.* Otherwise, it checks if the requesting client received an offer from the* server.** RETURNS: Matching resource, or NULL if none or not available.** ERRNO: N/A** NOMANUAL*//* * choose resource with ciaddr */static struct dhcp_resource * select_wciaddr    (    struct client_id *cid, 	/* pointer to identifier of request client */    time_t curr_epoch, 		/* current time, in seconds */    int *nosuchaddr 		/* flag indicating if address foun in table */    )    {    struct dhcp_resource *res = NULL;#ifdef DHCPS_DEBUG    char tmp [INET_ADDR_LEN];#endif    *nosuchaddr = FALSE;    res = (struct dhcp_resource *)hash_find (&iphashtable,                                       (char *)&dhcpsMsgIn.dhcp->ciaddr.s_addr,                                             sizeof (u_long), resipcmp,                                              &dhcpsMsgIn.dhcp->ciaddr);    if (res == NULL)         {        *nosuchaddr = TRUE;   /* Fatal error - expected entry not found. */        return (NULL);        }     else         {        /* Check for subnet match. */        if (cid->subnet.s_addr !=              (res->ip_addr.s_addr & res->subnet_mask.s_addr))             {#ifdef DHCPS_DEBUG            inet_ntoa_b (dhcpsMsgIn.dhcp->ciaddr, tmp);            logMsg ("Subnet mismatch for DHCPREQUEST (cid: %s, ciaddr: %s).\n",                     (int)cidtos (cid, 1), (int)tmp, 0, 0, 0, 0);#endif            return (NULL);            }        else if (ISSET(res->valid, S_CLIENT_ID))    /* Manual allocation. */            {            /* Fatal error if no binding present for manual allocation. */            if (res->binding == NULL)                 {#ifdef DHCPS_DEBUG                inet_ntoa_b (dhcpsMsgIn.dhcp->ciaddr, tmp);	        logMsg ("DHCPREQUEST(cid:\"%s\"): No binding for %s",                         (int)cidtos(cid, 1), (int)tmp, 0, 0, 0, 0);#endif	        *nosuchaddr = TRUE;	        return (NULL);                }            /* Check that client ID of binding matches requesting client. */            else if (res->binding->cid.idtype != cid->idtype ||	             res->binding->cid.idlen != cid->idlen ||	             bcmp (res->binding->cid.id, cid->id, cid->idlen) != 0)                     {#ifdef DHCPS_DEBUG                    inet_ntoa_b (dhcpsMsgIn.dhcp->ciaddr, tmp);	            logMsg (                  "DHCPREQUEST(cid:\"%s\", ciaddr:%s) - client ID mismatch.\n",                               (int)cidtos(cid, 1), (int)tmp, 0, 0, 0, 0);#endif	            return (NULL);                    }            }        /* Dynamic or automatic allocation. Fails if no binding present         * (i.e. - unknown request), or lease has expired (i.e. - late         * request), or if client ID doesn't match expected value from         * the DHCP offer message.         */        else if (res->binding == NULL ||	         (res->binding->expire_epoch != 0xffffffff &&	          res->binding->expire_epoch <= curr_epoch) ||	         res->binding->cid.idtype != cid->idtype ||	         res->binding->cid.idlen != cid->idlen ||	         bcmp (res->binding->cid.id, cid->id, cid->idlen) != 0)                  {#ifdef DHCPS_DEBUG                 inet_ntoa_b (dhcpsMsgIn.dhcp->ciaddr, tmp);                 logMsg ("DHCPREQUEST(cid:\"%s\",ciaddr:%s): is unavailable.\n",	                  (int)cidtos(cid, 1), (int)tmp, 0, 0, 0, 0);#endif                 return (NULL);                 }        }    return (res);    }/********************************************************************************* discover - handle client discover messages** This routine examines client discover messages, selects an available * resource (if any), calculates the length of the lease, and sends the * appropriate offer to the client.** RETURNS: 0 if processing successful, or -1 on error.** ERRNO: N/A** NOMANUAL*/static int discover    (    struct if_info *ifp    /* pointer to descriptor of receiving interface */    )    {    struct dhcp_resource *offer_res = NULL; /* lease descriptor chosen */    struct client_id cid;  			/* ID of requesting client */    u_long offer_lease = 0; 			/* offered lease duration */    u_long reqlease = 0; 			/* requested lease duration */    time_t curr_epoch = 0; 			/* current time, in seconds */    int result; 				/* error value, if any */    bzero ((char *)&cid, sizeof (cid));    if (dhcpTime (&curr_epoch) == -1)         {#ifdef DHCPS_DEBUG        logMsg ("Warning: discover() couldn't retrieve current time.\n",                 0, 0, 0, 0, 0, 0);#endif        return (-1);        }    /* Extract requested lease from DHCP message. */    reqlease = get_reqlease (dhcpsMsgIn.dhcp, rdhcplen);    /* Determine maximum length available in DHCP message for options. */    maxoptlen = get_maxoptlen (dhcpsMsgIn.dhcp, rdhcplen);    /* Set pointers to access client ID within DHCP message options field. */    get_cid (dhcpsMsgIn.dhcp, rdhcplen, &cid);    /* Critical section with dhcpsLeaseEntryAdd(). */    semTake (dhcpsMutexSem, WAIT_FOREVER);    /* Retrieve subnet for incoming message. */    if (get_subnet (dhcpsMsgIn.dhcp, rdhcplen, &cid.subnet, ifp) != 0)        {         semGive (dhcpsMutexSem);        return (-1);        }    /* Select an available lease descriptor. */    if ( (offer_res = choose_res (&cid, curr_epoch, reqlease)) == NULL)        {        semGive (dhcpsMutexSem);        return (-1);        }    /* Select a lease duration. */    offer_lease = choose_lease (reqlease, curr_epoch, offer_res);    /* Record lease offer in data structures. */    result = update_db (DHCPDISCOVER, &cid, offer_res, offer_lease, curr_epoch);    semGive (dhcpsMutexSem);    if (result != 0)        return (-1);    /* Create outgoing DHCP offer message. */    construct_msg (DHCPOFFER, offer_res, offer_lease, ifp);    /*     * xxx must be able to handle the fragments, but currently not implemented     */    /* Transfer message to receiving interface. */    send_dhcp (ifp, DHCPOFFER);    return (0);    }/********************************************************************************* request - handle client request messages** This routine responds to request messages sent by clients in response* to an offer from a DHCP server. If the server generated the offer, it* sends the appropriate ACK or NAK message. Otherwise, it updates the * internal data structure to reflect the implicit decline from the client.** RETURNS: 0 if processing successful, or -1 on error.** ERRNO: N/A** NOMANUAL*/static int request    (    struct if_info *ifp    /* pointer to descriptor of receiving interface */    )    {    BOOL reqforme = FALSE;    BOOL nosuchaddr = FALSE;    struct dhcp_resource *res = NULL;    struct client_id cid;    struct in_addr reqip;    struct in_addr netmask;    unsigned long offer_lease = 0;         /* offering lease */    unsigned long reqlease = 0;            /* requested lease duration */    char *option = NULL;    int response;                 /* Accept request? */#define EPOCH      "Thu Jan  1 00:00:00 1970\n"#define BRDCSTSTR  "255.255.255.255"    char datestr [sizeof (EPOCH)];    char addrstr [sizeof (BRDCSTSTR)];    time_t curr_epoch = 0;                 /* current epoch */    bzero ((char *)&cid, sizeof (cid));    bcopy (EPOCH, datestr, sizeof (EPOCH));    bcopy (BRDCSTSTR, addrstr, sizeof (BRDCSTSTR));    response = 2;            /* Response not determined. */    if (dhcpTime (&curr_epoch) == -1)        {#ifdef DHCPS_DEBUG        logMsg ("Warning: Couldn't get timestamp when processing request.\n",                 0, 0, 0, 0, 0, 0);#endif        return (-1);        }    reqlease = get_reqlease (dhcpsMsgIn.dhcp, rdhcplen);    maxoptlen = get_maxoptlen (dhcpsMsgIn.dhcp, rdhcplen);    get_cid (dhcpsMsgIn.dhcp, rdhcplen, &cid);    /* Critical section with dhcpsLeaseEntryAdd(). */    semTake (dhcpsMutexSem, WAIT_FOREVER);    if (get_subnet (dhcpsMsgIn.dhcp, rdhcplen, &cid.subnet, ifp) != 0)        {         semGive (dhcpsMutexSem);        return (-1);        }    /*     * Check if this DHCP server is the request destination.      * (Option not present unless client is in SELECTING state).       */    option = pickup_opt (dhcpsMsgIn.dhcp, rdhcplen, _DHCP_SERVER_ID_TAG);    if (option != NULL)         if (htonl (GETHL (OPTBODY (option))) == ifp->ipaddr.s_addr)            reqforme = TRUE;    /*     * Check the previously allocated network address sent by client     * (i.e. - client is in RENEWING or REBINDING state).      */     if (dhcpsMsgIn.dhcp->ciaddr.s_addr != 0)         {        /* For client in RENEWING state, no relay agents are used. */                if (get_snmk (dhcpsMsgIn.dhcp, rdhcplen, &netmask, ifp) == 0)             if (dhcpsMsgIn.dhcp->giaddr.s_addr != 0)                 /* REBINDING state - check network of client. */	        if ( (dhcpsMsgIn.dhcp->giaddr.s_addr & netmask.s_addr) !=	             (dhcpsMsgIn.dhcp->ciaddr.s_addr & netmask.s_addr))	            /* goto nak;   */               /* Different subnet. */                    response = 0;          /* Send NAK to client. */                if (response != 0)    /* Response still not determined. */            {            res = select_wciaddr (&cid, curr_epoch, &nosuchaddr);            if (res == NULL)                 {                /*                  * If no entry present or manual entry present without a                  * matching binding the request is meant for another server                 * (for renewal request) or cannot be satisfied (for rebinding).                 */                if (nosuchaddr == TRUE)                    {                    semGive (dhcpsMutexSem);                    return (-1);                    }                /* deny request for subnet mismatch, client ID mismatch,                 * expired lease, or missing binding for non-manual allocation.                 * (Missing binding means no DISCOVER received for request).                  */                 else      

⌨️ 快捷键说明

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