📄 dhcpclib.c
字号:
errno = S_dhcpcLib_BAD_DEVICE; return (NULL); } } else bufSize = dhcpcBufSize + sizeof (struct bpf_hdr); /* Allocate all lease-specific variables. */ pLeaseData = (LEASE_DATA *)calloc (1, sizeof (LEASE_DATA)); if (pLeaseData == NULL) { close (bpfDev); errno = S_dhcpcLib_MEM_ERROR; return (NULL); } pLeaseData->initFlag = FALSE; pLeaseData->autoConfig = autoConfig; /* * Use the current data storage hook routine (if any) * throughout the lifetime of this lease. */ pLeaseData->cacheHookRtn = dhcpcCacheHookRtn; /* * For now, use the lease data pointer as the unique lease identifier. * This could be changed later to shield the internal structures from * the user, but it allows fast data retrieval. */ pCookie = (void *)pLeaseData; pReqSpec = &pLeaseData->leaseReqSpec; bzero ( (char *)pReqSpec, sizeof (struct dhcp_reqspec)); bzero ( (char *)&pLeaseData->ifData, sizeof (struct if_info)); /* Initialize WIDE project global containing network device data. */ sprintf (pLeaseData->ifData.name, "%s", pIf->if_name); pLeaseData->ifData.unit = pIf->if_unit; pLeaseData->ifData.iface = pIf; pLeaseData->ifData.bpfDev = bpfDev; pLeaseData->ifData.bufSize = bufSize; /* * For END devices, use hardware address information set when * driver attached to IP. Assume BSD devices use Ethernet frames. */ if (bsdFlag) pLeaseData->ifData.haddr.htype = ETHER; else pLeaseData->ifData.haddr.htype = dhcpConvert (pIf->if_type); pLeaseData->ifData.haddr.hlen = pIf->if_addrlen; if (pLeaseData->ifData.haddr.hlen > MAX_HLEN) pLeaseData->ifData.haddr.hlen = MAX_HLEN; bcopy ( (char *) ( (struct arpcom *)pIf)->ac_enaddr, (char *)&pLeaseData->ifData.haddr.haddr, pLeaseData->ifData.haddr.hlen); /* * Set the maximum message length based on the MTU size and the * maximum message/buffer size specified during initialization. */ pReqSpec->maxlen = maxSize; /* set duration of client's wait for multiple offers */ pReqSpec->waitsecs = dhcpcOfferTimeout; pReqSpec->reqlist.len = 0; /* No options requested yet. */ /* * If executing with startup lease, or if automatic configuration is * requested, initialize request list with tags for options required * by all network interfaces, using RFC 1533 tag values. */ if (pLeaseData->autoConfig || pLeaseData->leaseType == DHCP_AUTOMATIC) { pReqSpec->reqlist.list [pReqSpec->reqlist.len++] = _DHCP_SUBNET_MASK_TAG; pReqSpec->reqlist.list [pReqSpec->reqlist.len++] = _DHCP_BRDCAST_ADDR_TAG; } /* * For now, create a separate watchdog timer for each lease. Eventually, * a single watchdog timer will suffice for all leases, when combined * with a sorted queue containing relative firing times. This enhancement * can wait. */ /* Create event timer for state machine. */ pLeaseData->timer = wdCreate (); if (pLeaseData->timer == NULL) { free (pLeaseData); close (bpfDev); errno = S_dhcpcLib_MEM_ERROR; return (NULL); } /* Create signalling semaphore for completion of negotiation process. */ pLeaseData->leaseSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY); if (pLeaseData->leaseSem == NULL) { wdDelete (pLeaseData->timer); free (pLeaseData); close (bpfDev); errno = S_dhcpcLib_MEM_ERROR; return (NULL); } /* * Manual leases will not reset the network interface unless specifically * requested to do so. This lease type is replaced with DHCP_AUTOMATIC for * the lease established during system startup. The parameters for * an automatic lease are always applied to the underlying interface. */ pLeaseData->leaseType = DHCP_MANUAL; pLeaseData->initFlag = TRUE; /* Store the lease-specific data in the global list. */ dhcpcLeaseList [offset] = pLeaseData; /* Notify the DHCP read task that a new session is available. */ send (dhcpcSignalSock, dhcpcSignalData, dhcpcSignalSize, 0); return (pCookie); }/********************************************************************************* dhcpcEventHookAdd - add a routine to handle configuration parameters** This routine installs a hook routine to handle changes in the configuration* parameters provided for the lease indicated by <pCookie>. The hook provides * an alternate configuration method for DHCP leases and uses the following * interface:* .CS* void dhcpcEventHookRtn* (* int leaseEvent, /@ new or expired parameters @/* void * pCookie /@ lease identifier from dhcpcInit() @/* )* .CE** The routine is called with the <leaseEvent> parameter set to DHCPC_LEASE_NEW* whenever a lease is successfully established. The DHCPC_LEASE_NEW event* does not occur when a lease is renewed by the same DHCP server, since the* parameters do not change in that case. However, it does occur if the * client rebinds to a different DHCP server. The DHCPC_LEASE_INVALID event* indicates that the configuration parameters for the corresponding lease may* no longer be used. That event occurs when a lease expires or a renewal* or verification attempt fails, and coincides with re-entry into the initial * state of the negotiation process.** If the lease initialization specified automatic configuration of the* corresponding network interface, any installed hook routine will be invoked* after the new address information is applied.** RETURNS: OK if notification hook added, or ERROR otherwise.** ERRNO: S_dhcpcLib_BAD_COOKIE, S_dhcpcLib_NOT_INITIALIZED*/STATUS dhcpcEventHookAdd ( void * pCookie, /* identifier returned by dhcpcInit() */ FUNCPTR pEventHook /* routine to handle lease parameters */ ) { LEASE_DATA * pLeaseData; int offset; /* * 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); } /* Assign the event notification hook. */ pLeaseData->eventHookRtn = pEventHook; return (OK); }/********************************************************************************* dhcpcEventHookDelete - remove the configuration parameters handler** This routine removes the hook routine that handled changes in the * configuration parameters for the lease indicated by <pCookie>.* If the lease initialization specified automatic configuration of the* corresponding network interface, the assigned address could change* without warning after this routine is executed.** RETURNS: OK if notification hook removed, or ERROR otherwise.** ERRNO: S_dhcpcLib_BAD_COOKIE, S_dhcpcLib_NOT_INITIALIZED* */STATUS dhcpcEventHookDelete ( void * pCookie /* identifier returned by dhcpcInit() */ ) { LEASE_DATA * pLeaseData; int offset; /* * 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); } /* Remove the event notification hook. */ pLeaseData->eventHookRtn = NULL; return (OK); }/********************************************************************************* dhcpcCacheHookAdd - add a routine to store and retrieve lease data** This routine adds a hook routine that is called at the bound state* (to store the lease data) and during the INIT_REBOOT state (to re-use the* parameters if the lease is still active). The calling sequence of the * input hook routine is:* .CS* STATUS dhcpcCacheHookRtn* (* int command, /@ requested cache operation @/* unsigned long *pTimeStamp, /@ lease timestamp data @/* int *pDataLen, /@ length of data to access @/* char *pBuffer /@ pointer to data buffer @/* )** .CE* The hook routine should return OK if the requested operation is completed* successfully, or ERROR otherwise. All the supplied pointers reference memory * locations that are reused upon return from the hook. The hook routine * must copy the data elsewhere.** NOTE* The setting of the cache hook routine during a dhcpcInit() call is* recorded and used by the resulting lease throughout its lifetime.* Since the hook routine is intended to store a single lease record,* a separate hook routine should be specified before the dhcpcInit()* call for each lease which will re-use its parameters across reboots.** IMPLEMENTATION* The <command> parameter specifies one of the following operations:* .IP DHCP_CACHE_WRITE 25* Save the indicated data. The write operation must preserve the value* referenced by <pTimeStamp> and the contents of <pBuffer>. The <pDataLen> * parameter indicates the number of bytes in that buffer.* .IP DHCP_CACHE_READ * Restore the saved data. The read operation must copy the data from the* most recent write operation into the location indicated by <pBuffer>,* set the contents of <pDataLen> to the amount of data provided, and store * the corresponding timestamp value in <pTimeStamp>.* .IP* The read operation has very specific requirements. On entry, the value * referenced by <pDataLen> indicates the maximum buffer size available at* <pBuffer>. If the amount of data stored by the previous write exceeds this * value, the operation must return ERROR. A read must also return ERROR if the * saved timestamp value is 0. Finally, the read operation must return ERROR if * it is unable to retrieve all the data stored by the write operation or if the* previous write was unsuccessful.* .IP DHCP_CACHE_ERASE * Ignore all stored data. Following this operation, subsequent read operations* must return ERROR until new data is written. All parameters except * <command> are NULL.* .LP** RETURNS: OK, always.** ERRNO: N/A*/STATUS dhcpcCacheHookAdd ( FUNCPTR pCacheHookRtn /* routine to store/retrieve lease data */ ) { dhcpcCacheHookRtn = pCacheHookRtn; return (OK); }/********************************************************************************* dhcpcCacheHookDelete - delete a lease data storage routine** This routine deletes the hook used to store lease data, preventing* re-use of the configuration parameters across system reboots for* all subsequent lease attempts. Currently active leases will continue* to use the routine specified before the lease initialization.** RETURNS: OK, always.** ERRNO: N/A*/STATUS dhcpcCacheHookDelete (void) { dhcpcCacheHookRtn = NULL; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -