📄 dhcpclib.c
字号:
long length, /* length of data (if any) or 0 if unused */ char * pData /* option data, or NULL if none */ ) { LEASE_DATA * pLeaseData; struct dhcp_reqspec * pReqSpec; u_long result; /* * Use the cookie to access the lease-specific data structures. For now, * just typecast the cookie. This translation could be replaced with a more * sophisticated lookup at some point. */ pLeaseData = (LEASE_DATA *)pCookie; pReqSpec = &pLeaseData->leaseReqSpec; switch (option) /* Check for restricted options. */ { case _DHCP_PAD_TAG: /* fall-through */ case _DHCP_OPT_OVERLOAD_TAG: /* fall-through */ case _DHCP_MSGTYPE_TAG: /* fall-through */ case _DHCP_SERVER_ID_TAG: /* fall-through */ case _DHCP_REQ_LIST_TAG: /* fall-through */ case _DHCP_MAXMSGSIZE_TAG: /* fall-through */ case _DHCP_END_TAG: errno = S_dhcpcLib_BAD_OPTION; return (ERROR); break; default: break; } if (option < 0 || option > _DHCP_LAST_OPTION) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } if (pReqSpec->reqlist.len == _DHCP_MAX_OPTLEN) { switch (option) /* Ignore error for options not in request list. */ { case _DHCP_VENDOR_SPEC_TAG: /* fall-through */ case _DHCP_REQUEST_IPADDR_TAG: /* fall-through */ case _DHCP_LEASE_TIME_TAG: /* fall-through */ case _DHCP_ERRMSG_TAG: /* fall-through */ case _DHCP_CLASS_ID_TAG: /* fall-through */ case _DHCP_CLIENT_ID_TAG: /* fall-through */ break; default: /* Request list is full. */ errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); break; } } switch (option) { case _DHCP_VENDOR_SPEC_TAG: if (length < 1 || length > _DHCP_MAX_OPTLEN) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } if (pData == NULL) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } bcopy (pData, pReqSpec->vendlist.list, (int)length); pReqSpec->vendlist.len = (u_char)length; break; case _DHCP_REQUEST_IPADDR_TAG: result = inet_addr (pData); if (result == ERROR) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } pReqSpec->ipaddr.s_addr = result; break; case _DHCP_LEASE_TIME_TAG: pReqSpec->lease = value; break; case _DHCP_ERRMSG_TAG: pReqSpec->dhcp_errmsg = pData; break; case _DHCP_CLASS_ID_TAG: if (length < 1 || length > _DHCP_MAX_OPTLEN) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } if (pData == NULL) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } pReqSpec->classId = calloc (1, sizeof (struct class_id)); if (pReqSpec->classId == NULL) { errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); } pReqSpec->classId->id = calloc (length, sizeof (char)); if (pReqSpec->classId->id == NULL) { errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); } bcopy (pData, pReqSpec->classId->id, (int)length); pReqSpec->classId->len = (u_char)length; break; case _DHCP_CLIENT_ID_TAG: if (length < 1 || length > _DHCP_MAX_OPTLEN) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } if (pData == NULL) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } pReqSpec->clid = calloc (1, sizeof (struct client_id)); if (pReqSpec->clid == NULL) { errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); } pReqSpec->clid->id = calloc (length, sizeof (char)); if (pReqSpec->clid->id == NULL) { errno = S_dhcpcLib_OPTION_NOT_STORED; return (ERROR); } bcopy (pData, pReqSpec->clid->id, (int)length); pReqSpec->clid->len = (unsigned char)length; pReqSpec->clid->type = (unsigned char)value; break; default: pReqSpec->reqlist.list [pReqSpec->reqlist.len++] = option; break; } return (OK); }/********************************************************************************* dhcpcBind - obtain a set of network configuration parameters with DHCP** This routine initiates a DHCP negotiation according to the process described * in RFC 1541. The <pCookie> argument contains the return value of an earlier * dhcpcInit() call and is used to identify a particular lease.** The <syncFlag> parameter specifies whether the DHCP negotiation started by * this routine will execute synchronously or asynchronously. An asynchronous * execution will return after starting the DHCP negotiation, but a synchronous * execution will only return once the negotiation process completes.** When a new lease is established, any event hook provided for the lease* will be called to process the configuration parameters. The hook is also * called when the lease expires or the negotiation process fails. The results * of an asynchronous DHCP negotiation are not available unless an event hook * is installed.** If automatic configuration of the underlying network interface was specified* during the lease initialization, this routine will prevent all higher-level * protocols from accessing the underlying network interface used during the * initial lease negotiation until that process is complete. In addition, any * addressing information obtained will be applied to that network interface, * which will remain disabled if the initial negotiation fails. Finally, the* interface will be disabled if the lease expires.** NOTE* If the DHCP client is used to obtain the VxWorks boot parameters, this * routine is called automatically during system startup using the automatic * reconfiguration. Therefore, any calls to this routine which use the network * boot device for message transfer when the DHCP client was used at boot time * must not request automatic reconfiguration during initialization. Otherwise, * the resulting lease settings will conflict with the configuration maintained * by the lease established during system startup. ** RETURNS: OK if routine completes, or ERROR otherwise.** ERRNO: S_dhcpcLib_BAD_COOKIE, S_dhcpcLib_NOT_INITIALIZED, S_dhcpcLib_BAD_OPTION* */STATUS dhcpcBind ( void * pCookie, /* identifier returned by dhcpcInit() */ BOOL syncFlag /* synchronous or asynchronous execution */ ) { int offset; STATUS result = OK; LEASE_DATA * pLeaseData = NULL; /* * Use the cookie to access the lease-specific data structures. For now, * just typecast the cookie. This translation could be replaced with a more * sophisticated lookup at some point. */ pLeaseData = (LEASE_DATA *)pCookie; for (offset = 0; offset < dhcpcMaxLeases; offset++) if (dhcpcLeaseList [offset] != NULL && dhcpcLeaseList [offset] == pLeaseData) break; if (offset == dhcpcMaxLeases) { errno = S_dhcpcLib_BAD_COOKIE; return (ERROR); } if (!dhcpcInitialized || !pLeaseData->initFlag) { errno = S_dhcpcLib_NOT_INITIALIZED; return (ERROR); } if (syncFlag != TRUE && syncFlag != FALSE) { errno = S_dhcpcLib_BAD_OPTION; return (ERROR); } /* Examine type of DHCP lease to determine action required. */ if (pLeaseData->leaseType == DHCP_BOOTP) { return (OK); /* BOOTP leases are always valid. */ } /* Wait for results if the startup lease is being renewed. */ if (pLeaseData->leaseType == DHCP_AUTOMATIC) pLeaseData->waitFlag = TRUE; else pLeaseData->waitFlag = syncFlag; if (pLeaseData->leaseType == DHCP_MANUAL && pLeaseData->leaseGood) { /* If redundant bind is requested, change to verification. */ result = dhcpcVerify (pCookie); return (result); } else /* Obtain initial lease or renew startup lease. */ { dhcp_client (pCookie); /* Perform bind process. */ /* Check results of synchronous lease attempt. */ if (pLeaseData->waitFlag) { pLeaseData->waitFlag = FALSE; /* Disable further signals. */ semTake (dhcpcMutexSem, WAIT_FOREVER); if (pLeaseData->leaseGood) result = OK; else result = ERROR; semGive (dhcpcMutexSem); } else result = OK; } /* * If waitFlag was TRUE, the negotiation has completed. Otherwise, it * has begun, and the installed event hook routine will be called at the * appropriate time. */ return (result); }/********************************************************************************* dhcpcVerify - renew an established lease** This routine schedules the lease identified by the <pCookie> parameter* for immediate renewal according to the process described in RFC 1541.* If the renewal is unsuccessful, the lease negotiation process restarts.* The routine is valid as long as the lease is currently active. The* routine is also called automatically in response to a dhcpcBind() call* for an existing lease.** NOTE* This routine will disable the underlying network interface if the * verification fails and automatic configuration was requested. This may* occur without warning if no event hook is installed.** RETURNS: OK if verification scheduled, or ERROR otherwise.** ERRNO: S_dhcpcLib_BAD_COOKIE, S_dhcpcLib_NOT_INITIALIZED, S_dhcpcLib_NOT_BOUND* */STATUS dhcpcVerify ( void * pCookie /* identifier returned by dhcpcInit() */ ) { int offset; LEASE_DATA * pLeaseData = NULL; STATUS result = OK; /* * Use the cookie to access the lease-specific data structures. For now, * just typecast the cookie. This translation could be replaced with a more * sophisticated lookup at some point. */ pLeaseData = (LEASE_DATA *)pCookie; for (offset = 0; offset < dhcpcMaxLeases; offset++) if (dhcpcLeaseList [offset] != NULL && dhcpcLeaseList [offset] == pLeaseData) break; if (offset == dhcpcMaxLeases) { errno = S_dhcpcLib_BAD_COOKIE; return (ERROR); } if (!dhcpcInitialized || !pLeaseData->initFlag) { errno = S_dhcpcLib_NOT_INITIALIZED; return (ERROR); } semTake (dhcpcMutexSem, WAIT_FOREVER); if (!pLeaseData->leaseGood) result = ERROR; semGive (dhcpcMutexSem); if (result == ERROR) { errno = S_dhcpcLib_NOT_BOUND; return (ERROR); } /* Construct and send a verification request to the client monitor task. */ result = dhcpcEventAdd (DHCP_USER_EVENT, DHCP_USER_VERIFY, pLeaseData, FALSE); return (result); }/********************************************************************************* dhcpcRelease - relinquish specified lease** This routine schedules the lease identified by the <pCookie> parameter* for immediate release, regardless of time remaining, and removes all* the associated data structures. After the release completes, a new* call to dhcpcInit() is required before attempting another lease.** NOTE* This routine will disable the underlying network interface if automatic * configuration was requested. This may occur without warning if no event * hook is installed.** RETURNS: OK if release scheduled, or ERROR otherwise.** ERRNO: S_dhcpcLib_BAD_COOKIE, S_dhcpcLib_NOT_INITIALIZED**/STATUS dhcpcRelease ( void * pCookie /* identifier returned by dhcpcInit() */ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -