📄 dhcpclib.c
字号:
pUdph->uh_sport = 0; pUdph->uh_dport = htons (clientPort); pUdph->uh_ulen = htons (UDPHL + 1); dhcpcSignalData [UDPHL + IPHL] = 'a'; /* Create a socket to send and receive DHCP messages. */ dhcpcDataSock = socket (AF_INET, SOCK_DGRAM, 0); if (dhcpcDataSock < 0) { close (dhcpcSignalSock); return (ERROR); } bzero ( (char *)&dstaddr, sizeof (dstaddr)); dstaddr.sin_family = AF_INET; dstaddr.sin_addr.s_addr = htonl (INADDR_ANY); dstaddr.sin_port = htons (clientPort); result = bind (dhcpcDataSock, (struct sockaddr *) &dstaddr, sizeof (dstaddr)); if (result != OK) { close (dhcpcSignalSock); close (dhcpcDataSock); return (ERROR); } if (bpfDrv () == ERROR) { close (dhcpcSignalSock); close (dhcpcDataSock); return (ERROR); } bufSize = maxSize + sizeof (struct bpf_hdr); if (bpfDevCreate ("/bpf/dhcpc", maxLeases, bufSize) == ERROR) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDrvRemove (); return (ERROR); } /* Create and initialize storage for active leases. */ dhcpcLeaseList = malloc (maxLeases * sizeof (LEASE_DATA *)); if (dhcpcLeaseList == NULL) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } for (loop = 0; loop < maxLeases; loop++) dhcpcLeaseList [loop] = NULL; dhcpcMaxLeases = maxLeases; dhcpcDefaultLease = defaultLease; dhcpcOfferTimeout = offerTimeout; dhcpcMinLease = minLease; /* * Create protection semaphore for all lease status indicators. User * requests which require an active lease check this indicator before * executing. A single semaphore is used to reduce system resource * requirements, even though this behavior may allow user requests to * slightly delay status updates for unrelated leases. */ dhcpcMutexSem = semBCreate (SEM_Q_FIFO, SEM_FULL); if (dhcpcMutexSem == NULL) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); free (dhcpcLeaseList); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } /* Create signalling semaphore for event notification ring. */ dhcpcEventSem = semCCreate (SEM_Q_FIFO, 0); if (dhcpcEventSem == NULL) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); free (dhcpcLeaseList); semDelete (dhcpcMutexSem); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } /* Create event storage. */ dhcpcEventRing = rngCreate (EVENT_RING_SIZE); if (dhcpcEventRing == NULL) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); free (dhcpcLeaseList); semDelete (dhcpcMutexSem); semDelete (dhcpcEventSem); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } /* Create message storage (matches number of elements in event ring). */ dhcpcMessageList = malloc (10 * sizeof (MESSAGE_DATA)); if (dhcpcMessageList == NULL) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); free (dhcpcLeaseList); semDelete (dhcpcMutexSem); semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } /* Allocate receive buffers based on maximum message size. */ for (loop = 0; loop < 10; loop++) { dhcpcMessageList [loop].msgBuffer = memalign (4, bufSize); if (dhcpcMessageList [loop].msgBuffer == NULL) break; dhcpcMessageList [loop].writeFlag = TRUE; } if (loop < 10) { for (offset = 0; offset < loop; offset++) free (dhcpcMessageList [offset].msgBuffer); close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); free (dhcpcLeaseList); semDelete (dhcpcMutexSem); semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); free (dhcpcMessageList); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } /* Set up state machine and data structures for outgoing messages. */ result = dhcp_client_setup (serverPort, clientPort, maxSize); if (result == ERROR) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); free (dhcpcLeaseList); semDelete (dhcpcMutexSem); semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); for (offset = 0; offset < 10; offset++) free (dhcpcMessageList [offset].msgBuffer); free (dhcpcMessageList); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } dhcpcCacheHookRtn = NULL; /* * Spawn the monitor task. The entry routine will drive the client * state machine after processing all incoming DHCP messages and timer * related or user generated events. */ result = taskSpawn ("tDhcpcStateTask", _dhcpcStateTaskPriority, _dhcpcStateTaskOptions, _dhcpcStateTaskStackSize, (FUNCPTR) dhcpcState, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (result == ERROR) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); free (dhcpcLeaseList); semDelete (dhcpcMutexSem); semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); for (offset = 0; offset < 10; offset++) free (dhcpcMessageList [offset].msgBuffer); free (dhcpcMessageList); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } stateTaskId = result; /* * Spawn the data retrieval task. The entry routine will read all * incoming DHCP messages and signal the monitor task 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) { close (dhcpcSignalSock); close (dhcpcDataSock); bpfDevDelete ("/bpf/dhcpc"); bpfDrvRemove (); free (dhcpcLeaseList); semDelete (dhcpcMutexSem); semDelete (dhcpcEventSem); rngDelete (dhcpcEventRing); for (offset = 0; offset < 10; offset++) free (dhcpcMessageList [offset].msgBuffer); free (dhcpcMessageList); taskDelete (stateTaskId); errno = S_dhcpcLib_MEM_ERROR; return (ERROR); } dhcpcReadTaskId = result; dhcpcBufSize = maxSize; /* Reset the filter to use the specified client port. */ dhcpfilter [12].k = clientPort; /* Minimum IP and UDP packet lengths */ dhcpfilter [14].k = (DFLTDHCPLEN - DFLTOPTLEN + 4) + UDPHL + IPHL; dhcpfilter [16].k = (DFLTDHCPLEN - DFLTOPTLEN + 4) + UDPHL; dhcpcInitialized = TRUE; return (OK); }/********************************************************************************* dhcpcLeaseGet - read lease information from boot line** If an automatic configuration protocol was used by the bootstrap loader* (i.e. - SYSFLG_AUTOCONFIG was set), this routine is called to handle* possible DHCP values in the address string. If the target address indicated * by <pAddrString> contains both lease duration and lease origin values, it was* assigned by a DHCP server and the routine sets the status flag accessed by * <pDhcpStatus> so that the lease will be verified or renewed. This routine is * called when initializing the network during system startup and will not * function correctly if used in any other context. Any lease information * attached to the address string is removed when this routine is executed.** RETURNS: OK if setup completes, or ERROR if the address string is invalid.** ERRNO: N/A** NOMANUAL*/STATUS dhcpcLeaseGet ( char * pAddrString, /* client address string from bootline */ BOOL * pDhcpStatus /* DHCP lease values found? */ ) { char * pDelim; char * pOffset; int result; dhcpcBootLease.lease_duration = 0; /* Defaults to expired. */ dhcpcBootLease.lease_origin = 0; /* Defaults to invalid value. */ /* Read DHCP lease values and remove from address string. */ result = bootLeaseExtract (pAddrString, &dhcpcBootLease.lease_duration, &dhcpcBootLease.lease_origin); if (result == 2) *pDhcpStatus = TRUE; /* DHCP lease values read successfully. */ else { *pDhcpStatus = FALSE; /* Valid DHCP lease values not present. */ if (result == 0) { /* * The ":" field separator for either the netmask or duration was * not found, so no DHCP lease values are present. */ return (OK); } if (result == 1) { /* * Only the lease duration field was present. * The DHCP lease values have been removed. */ return (ERROR); } /* * Parsing one of the lease values failed. Remove * any DHCP lease data from the address string. */ /* Find delimiter for netmask. */ pOffset = index (pAddrString, ':'); /* * Start at the delimiter for DHCP lease values. The netmask separator * is actually always present at this point, but check for it anyway. */ if (pOffset != NULL) { pDelim = pOffset + 1; /* * Find the lease duration tag. This field separator is also * guaranteed to be present, or the extract routine would have * returned 0. */ pOffset = index (pDelim, ':'); /* Remove the DHCP lease values from string. */ if (pOffset != NULL) *pOffset = EOS; } return (ERROR); } return (OK); }/********************************************************************************* dhcpcConfigSet - set system configuration according to active DHCP lease** This routine verifies or renews any DHCP lease established during the system * boot. If a DHCP lease was established, the dhcpcInit() call in this routine* will setup the necessary data structures and create a cookie identifying the * boot lease. The cookie is stored in the pDhcpcBootCookie global variable to* provide users with access to the boot-time lease. This routine is called when* initializing the network during system startup and will not function* correctly if executed in any other context.** RETURNS: OK if configuration completed, or ERROR otherwise.** ERRNO: N/A** NOMANUAL*/STATUS dhcpcConfigSet ( BOOT_PARAMS * pParams, /* structure for parsed bootline */ char * pAddrString, /* specified IP address */ int * pNetmask, /* specified subnet mask */ BOOL * pDhcpStatus, /* DHCP used to get address? */ BOOL attachFlag /* Device configuration required? */ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -