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

📄 dhcps.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************* 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 */    struct dhcp_resource *res, 	/* pointer to lease descriptor */    u_long lease, 		/* lease duration, in seconds */    time_t curr_epoch 		/* current time, in seconds */    )    {    struct dhcp_binding *binding = NULL;    /*     * Ignore lease descriptors already offered (res->binding != NULL)     * if also reserved to specific clients (STATIC_ENTRY flag set).     */    if (res->binding != NULL && (res->binding->flag & STATIC_ENTRY) != 0)        return (0);    /* Remove old client identifier association from prior lease record. */    if (res->binding != NULL)         hash_del (&cidhashtable, res->binding->cid.id, res->binding->cid.idlen,	          bindcidcmp, &res->binding->cid, free_bind);    /* Create and assign new lease record entry. */    binding = (struct dhcp_binding *)calloc (1, sizeof (struct dhcp_binding));    if (binding == NULL)         {#ifdef DHCPS_DEBUG        logMsg ("Warning: memory allocation error updating database.\n",                  0, 0, 0, 0, 0, 0);#endif        return (-1);        }    if (cidcopy (cid, &binding->cid) != 0)        return (-1);    if (msgtype == DHCPDISCOVER)         binding->temp_epoch = curr_epoch + MEMORIZE;    else if (lease == 0xffffffff)         binding->expire_epoch = 0xffffffff;    else         binding->expire_epoch = curr_epoch + lease;    /* Link lease record and lease descriptor. */    binding->res = res;    bcopy (res->entryname, binding->res_name, strlen (res->entryname));    binding->res_name [strlen (res->entryname)] = '\0';    res->binding = binding;    /* Record client hardware address. */    binding->haddr.htype = dhcpsMsgIn.dhcp->htype;    binding->haddr.hlen = dhcpsMsgIn.dhcp->hlen;    if (binding->haddr.hlen > MAX_HLEN)        binding->haddr.hlen = MAX_HLEN;    bcopy (dhcpsMsgIn.dhcp->chaddr, binding->haddr.haddr, binding->haddr.hlen);    /* Add association of lease record and client identifier. */    if ( (hash_ins (&cidhashtable, binding->cid.id, binding->cid.idlen,                     bindcidcmp, &binding->cid, binding) < 0))         {#ifdef DHCPS_DEBUG        logMsg ("Warning: hash table insertion with client ID failed.\n",                 0, 0, 0, 0, 0, 0);#endif        return (-1);        }    /* Store record of lease. */    if (add_bind (binding) != 0)        return (-1);    return (0);    }/********************************************************************************* turnoff_bind - mark resource entry as unavailable** This routine updates the binding list and corresponding hash tables when* the server discovers (through an ICMP check or client decline) that an IP * address is unexpectedly in use. The corresponding resource is marked as an * active lease for the next half-hour.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static void turnoff_bind    (    struct dhcp_binding *binding 	/* unavailable lease record */    )    {    time_t curr_epoch = 0;    int result;    if (binding == NULL)        return;    if (dhcpTime (&curr_epoch) == -1)         {#ifdef DHCPS_DEBUG        logMsg ("Warning: turnoff_bind() can't retrieve current time.\n",                 0, 0, 0, 0, 0, 0);#endif        return;        }    /* Remove client ID from hash table entry for address in use. */    binding->expire_epoch = binding->temp_epoch = curr_epoch + 1800;    hash_del (&cidhashtable, binding->cid.id, binding->cid.idlen, bindcidcmp,	      &binding->cid, free_fake);    bzero (binding->cid.id, binding->cid.idlen);    result = hash_ins (&cidhashtable, binding->cid.id, binding->cid.idlen,                        bindcidcmp, &binding->cid, binding);#ifdef DHCPS_DEBUG    if (result < 0)         logMsg ("Warning: couldn't alter hash table in turnoff_bind()",                  0, 0, 0, 0, 0, 0);#endif    binding->flag &= ~COMPLETE_ENTRY;    return;    }/********************************************************************************* clean_sbuf - clean the message transmission buffers** This routine clears the vectored buffers used to store outgoing DHCP * messages. The first buffer contains the Ethernet, IP and UDP headers, as well* as the fixed-length portion of the DHCP message and the options which fit * within the default (312 byte) option field. The second buffer contains * overflow options, if any, for clients capable of receiving DHCP messages * longer than the default 548 bytes.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static void clean_sbuf (void)    {    bzero (sbufvec[0].iov_base, sbufvec[0].iov_len);    bzero (sbufvec[1].iov_base, sbufvec[1].iov_len);    sbufvec[1].iov_len = 0;    return;    }/********************************************************************************* construct_msg - make an outgoing DHCP message** This routine creates all DHCP server responses to client requests, according* to the behavior specified in RFC 1541. The message type parameter indicates* whether to build a DHCP offer message, a DHCP ACK message, or a NAK reply.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static void construct_msg    (    u_char msgtype, 		/* type of DHCP message to construct */    struct dhcp_resource *res, 	/* lease descriptor describing contents */    u_long lease, 		/* lease duration, in seconds */    struct if_info *ifp 	/* descriptor of receiving interface */    )    {    int i = 0;    int reqoptlen = 0;    u_long tmp = 0;    char *reqopt = NULL;    char inserted[32];    char *option = NULL;    struct client_id   paramId;   /* Key for additional parameters. */    struct dhcp_resource * params;   /* Client- or class-specific options. */    int result;    bzero (inserted, sizeof (inserted));    clean_sbuf ();            /* Zero out outgoing message buffer. */    dhcpsMsgOut.dhcp->op = BOOTREPLY;    dhcpsMsgOut.dhcp->htype = dhcpsMsgIn.dhcp->htype;    dhcpsMsgOut.dhcp->hlen = dhcpsMsgIn.dhcp->hlen;    dhcpsMsgOut.dhcp->hops = 0;    dhcpsMsgOut.dhcp->xid = dhcpsMsgIn.dhcp->xid;    dhcpsMsgOut.dhcp->secs = 0;    dhcpsMsgOut.dhcp->flags = dhcpsMsgIn.dhcp->flags;    dhcpsMsgOut.dhcp->giaddr.s_addr = dhcpsMsgIn.dhcp->giaddr.s_addr;    bcopy (dhcpsMsgIn.dhcp->chaddr, dhcpsMsgOut.dhcp->chaddr,           dhcpsMsgIn.dhcp->hlen);    if (msgtype == DHCPACK)   /* ciaddr stays zero for all other types. */        dhcpsMsgOut.dhcp->ciaddr.s_addr = dhcpsMsgIn.dhcp->ciaddr.s_addr;    if (msgtype != DHCPNAK)         {        dhcpsMsgOut.dhcp->yiaddr.s_addr = res->ip_addr.s_addr;        if (ISSET (res->valid, S_SIADDR))             {            dhcpsMsgOut.dhcp->siaddr.s_addr = res->siaddr.s_addr;            }         else             {            dhcpsMsgOut.dhcp->siaddr.s_addr = 0;            }        overload = BOTH_AREOPT;        if (ISSET (res->valid, S_SNAME))             {            strncpy (dhcpsMsgOut.dhcp->sname, res->sname, MAX_SNAME);            dhcpsMsgOut.dhcp->sname [MAX_SNAME - 1] = '\0';            overload -= SNAME_ISOPT;            }        if (ISSET (res->valid, S_FILE))             {            strncpy (dhcpsMsgOut.dhcp->file, res->file, MAX_FILE);            dhcpsMsgOut.dhcp->file [MAX_FILE - 1] = '\0';            overload -= FILE_ISOPT;            }        }     else         {        dhcpsMsgOut.dhcp->yiaddr.s_addr = 0;        dhcpsMsgOut.dhcp->siaddr.s_addr = 0;        /* Refinement for draft RFC. */        /* if (dhcpsMsgIn.giaddr.s_addr != 0)            SETBRDCAST (dhcpsMsgOut.dhcp->flags); */        }    /* insert magic cookie */    bcopy ((char *)dhcpCookie, dhcpsMsgOut.dhcp->options, MAGIC_LEN);    off_options = MAGIC_LEN;    off_extopt = 0;    /* insert dhcp message type option */    dhcpsMsgOut.dhcp->options [off_options++] = _DHCP_MSGTYPE_TAG;    dhcpsMsgOut.dhcp->options [off_options++] = 1;    dhcpsMsgOut.dhcp->options [off_options++] = msgtype;    /* Insert client ID when permitted. (Only allowed under draft RFC). */    if (msgtype == DHCPNAK)         {        SETBRDCST (dhcpsMsgOut.dhcp->flags);/*      option = pickup_opt (dhcpsMsgIn.dhcp, rdhcplen, _DHCP_CLIENT_ID_TAG);        if (option != NULL)             {            dhcpsMsgOut.dhcp->options [off_options++] = _DHCP_CLIENT_ID_TAG;            dhcpsMsgOut.dhcp->options [off_options++] = DHCPOPTLEN(option);            bcopy (option, &dhcpsMsgOut.dhcp->options [off_options],                   DHCPOPTLEN (option));            off_options += DHCPOPTLEN (option);            } */        return;        }    /* insert "server identifier" (required). */    dhcpsMsgOut.dhcp->options [off_options++] = _DHCP_SERVER_ID_TAG;    dhcpsMsgOut.dhcp->options [off_options++] = 4;    bcopy ( (char *)&ifp->ipaddr.s_addr,             &dhcpsMsgOut.dhcp->options [off_options], 4);    off_options += 4;    /* insert "subnet mask" (permitted). */    result = insert_opt (res, lease, _DHCP_SUBNET_MASK_TAG, inserted, PASSIVE);#ifdef DHCPS_DEBUG    if (result == E_NOMORE)         logMsg ("No space left in options field for DHCP%s",                 (int)((msgtype == DHCPOFFER) ? "OFFER" : "ACK"),                  0, 0, 0, 0, 0);#endif    /* insert "lease duration" (required). */    tmp = htonl (lease);    dhcpsMsgOut.dhcp->options [off_options++] = _DHCP_LEASE_TIME_TAG;    dhcpsMsgOut.dhcp->options [off_options++] = 4;    bcopy ( (char *)&tmp, &dhcpsMsgOut.dhcp->options [off_options],             sizeof (u_long));    off_options += 4;    /* Insert "option overload" tag, if needed. */    if (overload != 0)         {        dhcpsMsgOut.dhcp->options[off_options++] = _DHCP_OPT_OVERLOAD_TAG;        dhcpsMsgOut.dhcp->options[off_options++] = 1;        dhcpsMsgOut.dhcp->options[off_options++] = overload;        }    /* insert the requested options */    option = pickup_opt(dhcpsMsgIn.dhcp, rdhcplen, _DHCP_REQ_LIST_TAG);    if (option != NULL)         {        reqopt = OPTBODY (option);        reqoptlen = DHCPOPTLEN (option);        /*          * Handle requested parameters. The PASSIVE flag only inserts options         * explicity configured into the resource entry. (Rule 1 of RFC 1541).         * Because the implementation used "tblc=dflt" to force inclusion of         * any missing parameters defined in the Host Requirements Document,         * the PASSIVE flag will also include those settings if not already          * present. (Rule 2 of RFC 1541).         */        for (i = 0; i < reqoptlen; i++)             if (ISCLR (inserted, * (reqopt + i)))                 {	        result = insert_opt (res, lease, * (reqopt + i), inserted,                                      PASSIVE);	        if (result == 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 parameters which differ from the Host Requirements RFC defaults.     * (The tags for these parameters are preceded by "!" in the server     * configuration table).     */    for (i = 0; i < _DHCP_LAST_OPTION; i++)         if (ISCLR (inserted, i))             if (insert_opt (res, lease, i, inserted, ACTIVE) == 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 client-specific options. */       /* Insert any parameters associated with explicit client identifier. */    tmp = 0;    option = pickup_opt (dhcpsMsgIn.dhcp, rdhcplen, _DHCP_CLIENT_ID_TAG);    if (option != NULL)        {        paramId.idlen = DHCPOPTLEN (option) - 1;        paramId.idtype = *(char *)OPTBODY (option);        bcopy (OPTBODY (option) + sizeof (char), 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) 

⌨️ 快捷键说明

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