📄 dhcpcbootlib.c
字号:
for (offset = 0; offset < 10; offset++) free (dhcpcMessageList [offset].msgBuffer); free (dhcpcMessageList); return (NULL); } /* Enable immediate mode for reading messages. */ result = 1; result = ioctl (bpfDev, BIOCIMMEDIATE, (int)&result); if (result != 0) { semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); for (offset = 0; offset < 10; offset++) free (dhcpcMessageList [offset].msgBuffer); free (dhcpcMessageList); close (bpfDev); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); return (NULL); } /* Initialize the lease-specific variables. */ bzero ( (char *)pBootLeaseData, sizeof (LEASE_DATA)); pBootLeaseData->initFlag = FALSE; pBootLeaseData->autoConfig = TRUE; pBootLeaseData->cacheHookRtn = NULL; /* Results are saved in bootline. */ pReqSpec = &pBootLeaseData->leaseReqSpec; bzero ( (char *)pReqSpec, sizeof (struct dhcp_reqspec)); bzero ( (char *)&pBootLeaseData->ifData, sizeof (struct if_info)); /* Initialize WIDE project global containing network device data. */ sprintf (pBootLeaseData->ifData.name, "%s", pIf->if_name); pBootLeaseData->ifData.unit = pIf->if_unit; pBootLeaseData->ifData.iface = pIf; pBootLeaseData->ifData.bpfDev = bpfDev; pBootLeaseData->ifData.bufSize = bufSize; /* * For END devices, use hardware address information set when * driver attached to IP. Assume BSD devices use Ethernet frames. */ if (bsdFlag) pBootLeaseData->ifData.haddr.htype = ETHER; else pBootLeaseData->ifData.haddr.htype = dhcpConvert (pIf->if_type); pBootLeaseData->ifData.haddr.hlen = pIf->if_addrlen; if (pBootLeaseData->ifData.haddr.hlen > MAX_HLEN) pBootLeaseData->ifData.haddr.hlen = MAX_HLEN; bcopy ( (char *) ( (struct arpcom *)pIf)->ac_enaddr, (char *)&pBootLeaseData->ifData.haddr.haddr, pBootLeaseData->ifData.haddr.hlen); /* * Set the maximum message length based on the MTU size and the * specified maximum message/buffer size. */ bufSize = pIf->if_mtu; if (bufSize > maxSize) pReqSpec->maxlen = maxSize; else pReqSpec->maxlen = bufSize; dhcpcBufSize = maxSize; /* set duration of client's wait for multiple offers */ pReqSpec->waitsecs = dhcpcOfferTimeout; /* * Initialize request list with tags for options provided by server, * according to RFC 2132. */ pReqSpec->reqlist.len = 0; pReqSpec->reqlist.list [pReqSpec->reqlist.len++] = _DHCP_SUBNET_MASK_TAG; pReqSpec->reqlist.list [pReqSpec->reqlist.len++] = _DHCP_BRDCAST_ADDR_TAG; /* Create event timer for state machine. */ pBootLeaseData->timer = wdCreate (); if (pBootLeaseData->timer == NULL) { semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); for (offset = 0; offset < 10; offset++) free (dhcpcMessageList [offset].msgBuffer); free (dhcpcMessageList); close (bpfDev); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); return (NULL); } pBootLeaseData->initFlag = TRUE; _dhcpcBootFlag = TRUE; /* Let read task ignore (unavailable) socket. */ /* * Spawn the data retrieval task. The entry routine will read all * incoming DHCP messages and signal the client state machine when a * valid one arrives. */ result = taskSpawn ("tDhcpcReadTask", _dhcpcReadTaskPriority, _dhcpcReadTaskOptions, _dhcpcReadTaskStackSize, (FUNCPTR) dhcpcRead, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (result == ERROR) { semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); for (offset = 0; offset < 10; offset++) free (dhcpcMessageList [offset].msgBuffer); free (dhcpcMessageList); close (bpfDev); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); wdDelete (pBootLeaseData->timer); return (NULL); } dhcpcReadTaskId = result; return (pBootLeaseData); }/********************************************************************************* dhcpcBootBind - initialize the network with DHCP at boot time** This routine performs the client side of a DHCP negotiation according to * RFC 2131. The negotiation uses the network device specified with the* initialization call. The addressing information retrieved is applied to that * network device. Because the boot image is replaced by the downloaded target * image, the resulting lease cannot be renewed. Therefore, the minimum lease * length specified by DHCPC_MIN_LEASE must be set so that the target image has * sufficient time to download and begin monitoring the lease. This routine is * called automatically by the boot program when INCLUDE_DHCPC is defined and * the automatic configuration option is set in the boot flags and no target* address is present.** RETURNS: OK if negotiation is successful, or ERROR otherwise.** ERRNO: N/A*/STATUS dhcpcBootBind (void) { STATUS result = OK; struct dhcpcOpts * pOptList; char * pOptions; struct ifreq ifr; /* * Allocate space for any options in outgoing messages * and fill in the options field. */ pOptList = dhcpcBootLeaseData.leaseReqSpec.pOptList; if (pOptList != NULL) { pOptions = malloc (pOptList->optlen); if (pOptions == NULL) { return (ERROR); } dhcpcBootLeaseData.leaseReqSpec.optlen = pOptList->optlen; dhcpcOptFieldCreate (pOptList, pOptions); free (pOptList); dhcpcBootLeaseData.leaseReqSpec.pOptList = NULL; dhcpcBootLeaseData.leaseReqSpec.pOptions = pOptions; } /* * Add a filter for incoming DHCP packets and assign the selected * interface to the BPF device. */ result = ioctl (dhcpcBootLeaseData.ifData.bpfDev, BIOCSETF, (int)&dhcpread); if (result != 0) { return (ERROR); } bzero ( (char *)&ifr, sizeof (struct ifreq)); sprintf (ifr.ifr_name, "%s%d", dhcpcBootLeaseData.ifData.name, dhcpcBootLeaseData.ifData.unit); result = ioctl (dhcpcBootLeaseData.ifData.bpfDev, BIOCSETIF, (int)&ifr); if (result != 0) { return (ERROR); } dhcpcBindType = DHCP_MANUAL; result = dhcp_boot_client (& (dhcpcBootLeaseData.ifData), dhcpcServerPort, dhcpcClientPort, TRUE); dhcpcBootCleanup (); if (result != OK) return (ERROR); /* Bind was successful. */ return (OK); }/********************************************************************************* dhcpcBootInformGet - obtain additional configuration parameters with DHCP** This routine uses DHCP to retrieve additional configuration parameters for* a client with the externally configured network address given by the* <pAddrString> parameter. It sends an INFORM message and waits for a reply* following the process described in RFC 2131. The message exchange uses* the network device specified with the initialization call. Any interface* information retrieved is applied to that network device. Since this process* does not establish a lease, the target address will not contain any* timestamp information so that the runtime image will not attempt to verify * the configuration parameters. This routine is called automatically by the* boot program when INCLUDE_DHCPC is defined and the automatic configuration* option is set in the boot flags if a target address is already present.** RETURNS: OK if negotiation is successful, or ERROR otherwise.** ERRNO: N/A*/STATUS dhcpcBootInformGet ( char * pAddrString /* known address assigned to client */ ) { STATUS result = OK; struct dhcpcOpts * pOptList; char * pOptions; /* Set the requested IP address field to the externally assigned value. */ dhcpcBootLeaseData.leaseReqSpec.ipaddr.s_addr = inet_addr (pAddrString); if (dhcpcBootLeaseData.leaseReqSpec.ipaddr.s_addr == -1) return (ERROR); /* * Allocate space for any options in outgoing messages * and fill in the options field. */ pOptList = dhcpcBootLeaseData.leaseReqSpec.pOptList; if (pOptList != NULL) { pOptions = malloc (pOptList->optlen); if (pOptions == NULL) { return (ERROR); } dhcpcBootLeaseData.leaseReqSpec.optlen = pOptList->optlen; dhcpcOptFieldCreate (pOptList, pOptions); free (pOptList); dhcpcBootLeaseData.leaseReqSpec.pOptList = NULL; dhcpcBootLeaseData.leaseReqSpec.pOptions = pOptions; } dhcpcBindType = DHCP_MANUAL; result = dhcp_boot_client (& (dhcpcBootLeaseData.ifData), dhcpcServerPort, dhcpcClientPort, FALSE); dhcpcBootCleanup (); if (result != OK) return (ERROR); /* Additional configuration parameters retrieved. */ return (OK); }/********************************************************************************* dhcpcBootParamsGet - retrieve current network parameters** This routine copies the configuration parameters obtained at boot time to * the caller-supplied structure. That structure contains non-NULL pointers to * indicate the parameters of interest. All other values within the structure * must be set to 0 before calling the routine. This routine is called * internally at boot time when the DHCP client is in the BOUND state.** RETURNS: OK if dhcpcBootParam is non-NULL, or ERROR otherwise.** ERRNO: N/A** NOMANUAL*/STATUS dhcpcBootParamsGet ( struct dhcp_param* pParamList ) { /* * If we were doing a DHCPINFORM and got no info, dhcpcBootParam * might still be NULL, in which case there are no parameters to * copy. Test for this here, otherwise dhcpcParamsCopy() will * blindly try to copy stuff from page 0. */ if (dhcpcBootParam == NULL) return (ERROR); dhcpcBootLeaseData.dhcpcParam = dhcpcBootParam; dhcpcParamsCopy (&dhcpcBootLeaseData, pParamList); return (OK); }/******************************************************************************** dhcpcBootCleanup - remove data structures used by boot-time DHCP client** This routine removes all data structures used by the dhcp client. It is * called internally when the client exits.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/LOCAL void dhcpcBootCleanup (void) { int loop; wdCancel (dhcpcBootLeaseData.timer); wdDelete (dhcpcBootLeaseData.timer); close (dhcpcBootLeaseData.ifData.bpfDev); taskDelete (dhcpcReadTaskId); semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); for (loop = 0; loop < 10; loop++) free (dhcpcMessageList [loop].msgBuffer); free (dhcpcMessageList); if (dhcpcBootLeaseData.leaseReqSpec.pOptions != NULL) { free (dhcpcBootLeaseData.leaseReqSpec.pOptions); } bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -