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

📄 dhcps.c

📁 vxworks下dhcpc,dhcpr,dhcps库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                      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 voidclean_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)                        == 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);

⌨️ 快捷键说明

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