📄 dhcpclib.c
字号:
{ char netDev [BOOT_DEV_LEN + 1]; struct dhcp_param bootParams; BOOL dhcpStatus; u_long result; struct ifnet * pIf; LEASE_DATA * pLeaseData; char bootFile[BOOT_FILE_LEN]; int netmask; dhcpStatus = *pDhcpStatus; if (dhcpStatus && !attachFlag) { /* * Fatal error: automatic configuration is required but not available. */ return (ERROR); } if (dhcpStatus == FALSE && pAddrString [0] != EOS) { /* * BOOTP reply was selected during system startup or the IP address * was assigned manually. Lease renewal (or new lease) is not needed. */ return (OK); } /* Verify DHCP lease obtained during boot or get a new one. */ bzero ( (char *)&bootParams, sizeof (struct dhcp_param)); if (((strncmp (pParams->bootDev, "scsi", 4) == 0) || (strncmp (pParams->bootDev, "ide", 3) == 0) || (strncmp (pParams->bootDev, "ata", 3) == 0) || (strncmp (pParams->bootDev, "fd", 2) == 0) || (strncmp (pParams->bootDev, "tffs", 4) == 0)) && pParams->other [0] != EOS) sprintf (netDev, "%s%d", pParams->other, pParams->unitNum); else sprintf (netDev, "%s%d", pParams->bootDev, pParams->unitNum); if (pAddrString [0] != EOS) { /* Fill in client address obtained from bootline. */ result = inet_addr (pAddrString); if (result == ERROR) { printf ("Invalid target address \"%s\"\n", pAddrString); return (ERROR); } dhcpcBootLease.yiaddr.s_addr = result; } pIf = ifunit (netDev); if (pIf == NULL) { printf ("Invalid device \"%s\"\n", netDev); return (ERROR); } /* * Initialize required variables and get the lease identifier. * The resulting lease will always apply the address information * to the specified network interface. */ pDhcpcBootCookie = dhcpcInit (pIf, TRUE); if (pDhcpcBootCookie == NULL) { printf ("Error initializing DHCP boot lease.\n"); return (ERROR); } if (pAddrString [0] != EOS) { unsigned long duration; /* * Setup to renew the boot lease. 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 *)pDhcpcBootCookie; /* Set the lease descriptor to identify the boot lease. */ pLeaseData->leaseType = DHCP_AUTOMATIC; /* Make sure the lease duration is in network byte order. */ duration = htonl(dhcpcBootLease.lease_duration); dhcpcOptionAdd (pDhcpcBootCookie, _DHCP_LEASE_TIME_TAG, 4, (UCHAR *)&duration); } /* * Execute the bind call synchronously to verify any boot lease * or get the required IP address. */ if (dhcpcBind (pDhcpcBootCookie, TRUE) != OK) { if (dhcpStatus == TRUE) printf ("Can't renew DHCP boot lease.\n"); else printf ("Can't get IP address for device.\n"); pDhcpcBootCookie = NULL; return (ERROR); } bootParams.file = bootFile; bootParams.subnet_mask = (struct in_addr *)&netmask; if (dhcpcParamsGet (pDhcpcBootCookie, &bootParams) == ERROR) { printf ("Can't get network data from DHCP lease.\n"); pDhcpcBootCookie = NULL; return (ERROR); } /* * The netmask is returned to us in network byte order, * but the caller expects it in host order. */ *pNetmask = ntohl(netmask); /* Fill in boot file */ if (bootParams.file[0] != EOS) bcopy (bootFile, pParams->bootFile, BOOT_FILE_LEN); /* Fill in host address. */ if (bootParams.siaddr.s_addr) inet_ntoa_b (bootParams.siaddr, pParams->had); /* Fill in new or verified target address. */ inet_ntoa_b (bootParams.yiaddr, pAddrString); /* Save timing information so later reboots will detect DHCP leases. */ dhcpcBootLease.lease_duration = bootParams.lease_duration; dhcpcBootLease.lease_origin = bootParams.lease_origin; /* Update status in case IP address is newly assigned. */ *pDhcpStatus = TRUE; return (OK); }/********************************************************************************* dhcpcInit - assign network interface and setup lease request** This routine creates the data structures used to obtain a set of parameters * with DHCP and must be called before each attempt at establishing a DHCP * lease, but after the dhcpcLibInit() routine has initialized the global data* structures.** The <pIf> argument indicates the network device which will be used for* transmission and reception of DHCP messages during the lifetime of the* lease. The DHCP client supports devices attached to the IP protocol* with the MUX/END interface. The specified device must be capable of* sending broadcast messages. It also supports BSD Ethernet devices* attached to the IP protocol. The MTU size of any interface must be large* enough to receive a minimum IP datagram of 576 bytes. If the interface MTU* size is less than the maximum message size set in the library initialization* it also determines the maximum length of the DHCP options field.** If the <autoConfig> parameter is set to TRUE, any address information* obtained will automatically be applied to the specified interface. The* <autoConfig> parameter also selects the default option request list for* a lease. If set to FALSE, no specific lease options are requested since* any configuration parameters obtained are not intended for the underlying* network device. In that case, any specific options required may be added* to the request list at any time before the corresponding dhcpcBind() call.* If <autoConfig> is TRUE, this routine sets the configuration parameters to* request the minimal address information (subnet mask and broadcast address)* necessary for reconfiguring the network device specified by <pIf>.** The internal lease identifier returned by this routine must be used in* subsequent calls to the DHCP client library.** NOTE* This routine is called automatically during system startup if the DHCP * client was used to obtain the VxWorks boot parameters. The resulting * lease will always reconfigure the network boot device. Therefore, any* further calls to this routine which specify the network boot device for * use in obtaining additional DHCP leases must set <autoConfig> to FALSE.* Otherwise, that device will be unable to maintain a stable configuration.* The global variable pDhcpcBootCookie provides access to the configuration * parameters for any DHCP lease created during system startup.* * RETURNS: Lease handle for later use, or NULL if lease setup fails.** ERRNO: S_dhcpcLib_NOT_INITIALIZED, S_dhcpcLib_BAD_DEVICE, S_dhcpcLib_BAD_OPTION,* S_dhcpcLib_MAX_LEASES_REACHED, S_dhcpcLib_MEM_ERROR** SEE ALSO* dhcpcOptionSet(), dhcpcEventHookAdd()*/void * dhcpcInit ( struct ifnet * pIf, /* network device used by client */ BOOL autoConfig /* reconfigure network device? */ ) { void * pCookie; LEASE_DATA * pLeaseData; struct dhcp_reqspec * pReqSpec; int offset; int result; int maxSize; /* Largest message, based on MTU and buffer sizes */ int bufSize; /* Size of internal BPF buffer for lease */ BOOL bsdFlag = FALSE; char bpfDevName [_DHCPC_MAX_DEVNAME]; /* "/bpf/dhcpc" + max unit number */ int bpfDev; if (!dhcpcInitialized) { errno = S_dhcpcLib_NOT_INITIALIZED; return (NULL); } if (pIf == NULL) { errno = S_dhcpcLib_BAD_DEVICE; return (NULL); } if (muxDevExists (pIf->if_name, pIf->if_unit) == FALSE) { bsdFlag = TRUE; } /* Verify interface data sizes are appropriate for message. */ if (pIf->if_mtu == 0) { errno = S_dhcpcLib_BAD_DEVICE; return (NULL); } maxSize = pIf->if_mtu; if (maxSize < DHCP_MSG_SIZE) { /* * Devices must accept messages equal to the minimum IP datagram * of 576 bytes, which corresponds to a DHCP message with up to * 312 bytes of options. */ errno = S_dhcpcLib_BAD_DEVICE; return (NULL); } /* Reduce maximum DHCP message to size of transmit buffer if necessary. */ if (maxSize > dhcpcBufSize) maxSize = dhcpcBufSize; if (autoConfig != TRUE && autoConfig != FALSE) { errno = S_dhcpcLib_BAD_OPTION; return (NULL); } /* Find an unused entry in the array of lease-specific variables. */ for (offset = 0; offset < dhcpcMaxLeases; offset++) if (dhcpcLeaseList [offset] == NULL) break; if (offset == dhcpcMaxLeases) { errno = S_dhcpcLib_MAX_LEASES_REACHED; return (NULL); } /* Get a BPF file descriptor to read/write DHCP messages. */ sprintf (bpfDevName, "/bpf/dhcpc%d", offset); bpfDev = open (bpfDevName, 0, 0); if (bpfDev < 0) { errno = S_dhcpcLib_BAD_DEVICE; return (NULL); } /* Enable immediate mode for reading messages. */ result = 1; result = ioctl (bpfDev, BIOCIMMEDIATE, (int)&result); if (result != 0) { close (bpfDev); errno = S_dhcpcLib_BAD_DEVICE; return (NULL); } /* * To save space, reset the internal BPF buffer to a value based * on the interface MTU size, if it is less than the maximum receive * buffer size assigned during the library initialization. The * DHCP client's read task handles the possibility of multiple * messages per receive buffer. */ bufSize = pIf->if_mtu + pIf->if_hdrlen; if (bufSize < dhcpcBufSize) { bufSize += sizeof (struct bpf_hdr); result = ioctl (bpfDev, BIOCSBLEN, (int)&bufSize); if (result != 0) { close (bpfDev); 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -