📄 dhcpslib.c
字号:
free (pTarget->dflt_irc_server.addr); if (pTarget->streettalk_server.addr != NULL) free (pTarget->streettalk_server.addr); if (pTarget->stda_server.addr != NULL) free (pTarget->stda_server.addr); if (pTarget->policy_filter.addr1 != NULL) free (pTarget->policy_filter.addr1); if (pTarget->policy_filter.addr2 != NULL) free (pTarget->policy_filter.addr2); if (pTarget->static_route.addr1 != NULL) free (pTarget->static_route.addr1); if (pTarget->static_route.addr2 != NULL) free (pTarget->static_route.addr2); free (pTarget); return; }/********************************************************************************* dhcpsLeaseEntryAdd - add another entry to the address pool** This routine allows the user to add new entries to the address pool without* rebuilding the VxWorks image. The routine requires a unique entry name of up* to eight characters, starting and ending IP addresses, and a colon-separated * list of parameters. Possible values for the parameters are listed in the * reference entry for dhcpsLib. The parameters also determine the type of * lease, which the server uses to determine priority when assigning lease * addresses. For examples of the possible lease types, see the reference * entry for dhcpsLib.** RETURNS: OK if entry read successfully, or ERROR otherwise.** ERRNO: N/A*/STATUS dhcpsLeaseEntryAdd ( char * pName, /* name of lease entry */ char * pStartIp, /* first IP address to assign */ char * pEndIp, /* last IP address in assignment range */ char * pParams /* formatted string of lease parameters */ ) { struct dhcp_resource *pResData = NULL; DHCPS_ENTRY_DESC entryData; struct hash_member *pListElem = NULL; int result; char tmp [10]; /* sizeof ("tblc=dlft") for host requirements defaults. */ char entryName [BASE_NAME + 1]; /* User-given name for address range. */ char newName [MAX_NAME + 1]; /* Unique name for each entry in range. */ char newAddress [INET_ADDR_LEN]; struct in_addr nextAddr; int len; char *pTmp; u_long start = 0; u_long end = 0; u_long loop; u_long limit; /* Ignore bad values for range. */ if (pStartIp != NULL && pEndIp == NULL) return (ERROR); if (pStartIp == NULL && pEndIp != NULL) return (ERROR); /* If no address specified, just process parameters once. */ if (pStartIp == NULL && pEndIp == NULL) { start = 0; end = 0; } else { start = inet_addr (pStartIp); end = inet_addr (pEndIp); if (start == ERROR || end == ERROR) return (ERROR); } entryData.pName = newName; entryData.pAddress = newAddress; entryData.pParams = pParams; len = strlen (pName); if (len > BASE_NAME) { bcopy (pName, entryName, BASE_NAME); entryName [BASE_NAME] = '\0'; } else { bcopy (pName, entryName, len); entryName [len] = '\0'; } limit = ntohl (end); for (loop = ntohl (start); loop <= limit; loop++) { pResData = (struct dhcp_resource *)calloc (1, sizeof (struct dhcp_resource)); if (pResData == NULL) { return (ERROR); } /* Generate a unique name by appending IP address value. */ sprintf (entryData.pName, "%s%lx", entryName, loop); /* Assign current IP address in range. */ nextAddr.s_addr = htonl (loop); inet_ntoa_b (nextAddr, entryData.pAddress); /* Critical section with message processing routines. */ semTake (dhcpsMutexSem, WAIT_FOREVER); if (process_entry (pResData, &entryData) < 0) { semGive (dhcpsMutexSem); dhcpsFreeResource (pResData); return (ERROR); } /* * Add Host Requirements defaults to resource entry. Do not add * to entries containing client-specific or class-specific * parameters. */ if (ISCLR (pResData->valid, S_PARAM_ID) && ISCLR (pResData->valid, S_CLASS_ID)) { sprintf (tmp, "%s", "tblc=dflt"); pTmp = tmp; eval_symbol (&pTmp, pResData); } /* Set default values for entry, if not already assigned. */ if (ISSET (pResData->valid, S_IP_ADDR)) set_default (pResData); /* * Append entries to lease descriptor list. Exclude entries which * specify additional client- or class-specific parameters. */ if (ISCLR (pResData->valid, S_PARAM_ID) && ISCLR (pResData->valid, S_CLASS_ID)) { pListElem = reslist; while (pListElem->next != NULL) pListElem = pListElem->next; pListElem->next = (struct hash_member *)calloc (1, sizeof (struct hash_member)); if (pListElem->next == NULL) { semGive (dhcpsMutexSem); dhcpsFreeResource (pResData); return (ERROR); } pListElem = pListElem->next; pListElem->next = NULL; pListElem->data = (void *)pResData; /* Add entryname to appropriate hash table. */ result = hash_ins (&nmhashtable, pResData->entryname, strlen (pResData->entryname), resnmcmp, pResData->entryname, pResData); if (result < 0) { semGive (dhcpsMutexSem); return (ERROR); } if (ISSET (pResData->valid, S_IP_ADDR)) if (hash_ins (&iphashtable, (char *)&pResData->ip_addr.s_addr, sizeof (u_long), resipcmp, &pResData->ip_addr, pResData) < 0) { semGive (dhcpsMutexSem); return (ERROR); } } /* Save entry in permanent storage, if hook is provided. */ if (dhcpsAddressHookRtn != NULL) (* dhcpsAddressHookRtn) (DHCPS_STORAGE_WRITE, pName, pStartIp, pEndIp, pParams); semGive (dhcpsMutexSem); } return (OK); }/******************************************************************************** * dhcpsLeaseHookAdd - assign a permanent lease storage hook for the server* * This routine allows the server to access some form of permanent storage* that it can use to store current lease information across restarts. The * only argument to dhcpsLeaseHookAdd() is a pointer to a storage routine * with the following interface: * .CS* STATUS dhcpsStorageHook (int op, char *buffer, int datalen);* .CE* The first parameter of the storage routine specifies one of the following * operations: * * DHCPS_STORAGE_START* DHCPS_STORAGE_READ* DHCPS_STORAGE_WRITE* DHCPS_STORAGE_STOP* DHCPS_STORAGE_CLEAR* * In response to START, the storage routine should prepare to return data or * overwrite data provided by earlier WRITEs. For a WRITE the storage routine * must save the contents of the buffer to permanent storage. For a READ, the * storage routine should copy data previously stored into the provided buffer * as a NULL-terminated string in FIFO order. For a CLEAR, the storage routine * should discard currently stored data. After a CLEAR, the READ operation* must return ERROR until additional data is stored. For a STOP, the storage * routine must handle cleanup. After a STOP, calls to the storage routine * must return error until a START is received. Each of these operations must * return OK if successful, or ERROR otherwise.* * Before the server is initialized, VxWorks automatically calls * dhcpsLeaseHookAdd(), passing in the routine name defined by DHCPS_LEASE_HOOK.* * RETURNS: OK, or ERROR if routine is NULL.* * ERRNO: N/A*/STATUS dhcpsLeaseHookAdd ( FUNCPTR pCacheHookRtn /* routine to store/retrieve lease records */ ) { if (pCacheHookRtn != NULL) { dhcpsLeaseHookRtn = pCacheHookRtn; return (OK); } return (ERROR); }/********************************************************************************* dhcpsAddressHookAdd - assign a permanent address storage hook for the server** This routine allows the server to access some form of permanent storage* to preserve additional address entries across restarts. This routine is* not required, but leases using unsaved addresses are not renewed. The * only argument provided is the name of a function with the following interface:* .CS* STATUS dhcpsAddressStorageHook (int op,* char *name, char *start, char *end, * char *params);* .CE* The first parameter of this storage routine specifies one of the following * operations: ** DHCPS_STORAGE_START* DHCPS_STORAGE_READ* DHCPS_STORAGE_WRITE* DHCPS_STORAGE_STOP ** In response to a START, the storage routine should prepare to return* data or overwrite data provided by earlier WRITE operations. For a * WRITE, the storage routine must save the contents of the four buffers * to permanent storage. Those buffers contain the NULL-terminated * strings received by the dhcpsLeaseEntryAdd() routine. For a READ, the* storage routine should copy previously stored data (as NULL-terminated * strings) into the provided buffers in the order received by earlier WRITE* operations. For a STOP, the storage routine should do any necessary cleanup. * After a STOP, the storage routine should return an ERROR for all operations * except START. ** The storage routine should return OK if successful, ERROR otherwise.** Note that, unlike the lease storage routine, there is no CLEAR operation.** Before the server is initialized, VxWorks calls this routine automatically * passing in the function named in DHCPS_ADDRESS_HOOK.** RETURNS: OK, or ERROR if function pointer is NULL.** ERRNO: N/A*/STATUS dhcpsAddressHookAdd ( FUNCPTR pCacheHookRtn /* routine to store/retrieve lease entries */ ) { /* * The hook routine is deliberately assigned before testing for NULL * so that this routine can be used to delete an existing address hook. * In that case, the user would just ignore the return value of ERROR. */ dhcpsAddressHookRtn = pCacheHookRtn; if (pCacheHookRtn == NULL) return (ERROR); return (OK); }/********************************************************************************* dhcpsInputHook - packet filter for DHCP client messages** This routine filters all DHCP client messages from incoming ethernet* traffic. It is called by the network interface driver when a new input* frame comes in from the network.* * RETURNS: TRUE if the ethernet frame is handle by this routine. No further* processing by the network driver is needed.* FALSE if the frame is not a DHCP client message. The ethernet frame* is then handled by the network driver.** ERRNO: N/A** NOMANUAL*/BOOL dhcpsInputHook ( struct ifnet * pIf, /* interface where packet was received */ char * pInput, /* contents of received packet */ int length /* length of received packet */ ) { int offset; struct if_info * pIfData; int retval; /* Return values */ struct ether_header * pEtherHdr; /* pointer to ethernet header */ struct ip * pIpHdr; /* pointer to IP header */ struct udphdr * pUdpHdr; /* pointer to UDP header */ EVENT_DATA newEvent; /* Find offset of receiving interface. */ offset = 0; pIfData = dhcpsIntfaceList; while (pIfData != NULL) { if ( (strcmp (pIf->if_name, pIfData->name) == 0) && (pIf->if_unit == pIfData->unit)) break; offset++; pIfData = pIfData->next; } if (pIfData == NULL) /* Unrecognized interface - ignore. */ { return (FALSE); } pEtherHdr = (struct ether_header *) pInput; pIpHdr = (struct ip *) &pInput [SIZEOF_ETHERHEADER];#if BSD<44 pUdpHdr = (struct udphdr *) &pInput [SIZEOF_ETHERHEADER + (pIpHdr->ip_v_hl & 0xf) * 4];#else pUdpHdr = (struct udphdr *) &pInput [SIZEOF_ETHERHEADER + pIpHdr->ip_hl * 4];#endif if (length <= SIZEOF_ETHERHEADER) return (FALSE); if (ntohs (pEtherHdr->ether_type) != ETHERTYPE_IP) return (FALSE); if (pIpHdr->ip_p != IPPROTO_UDP) return (FALSE); if (pUdpHdr->uh_dport != dhcps_port) return (FALSE); /* Message recognized - store and signal processing thread. */ /* Adjust message size (ignores trailers added by some drivers). */ if (length > DHCP_MSG_SIZE) length = DHCP_MSG_SIZE; newEvent.source = offset; newEvent.length = length; retval = rngBufPut (dhcpEventRing, (char *)&newEvent, sizeof (newEvent)); if (retval == sizeof (newEvent)) { /* Ignore storage error - notifications with no message are OK. */ rngBufPut (dhcpMsgRing, pInput, length); semGive (dhcpEventSem); } return (TRUE); }/********************************************************************************* alloc_sbuf - create message transmission buffers** This routine creates two transmission buffers for storing outgoing DHCP* messages. The first buffer has a fixed size equal to that of a standard * DHCP message as defined in the RFC. The second buffer contains the* remaining number of bytes available in an MTU. It is used if additional* space for DHCP options is needed and if the requesting client accepts* larger DHCP messages. The two buffers are stored in a "buffer vector"* structure.* * RETURNS: N/A* * ERRNO: N/A** NOMANUAL*/LOCAL STATUS alloc_sbuf (void) { char *pSendBuf; int sbufsize; /* * Allocate transmission buffer. Access at offset to provide 4-byte * alignment of IP header needed by Sun BSP's. */ sbufsize = ETHERHL + IPHL + UDPHL + DFLTDHCPLEN + DHCPS_OFF; dhcpsSendBuf = (char *)memalign (4, sbufsize); if (dhcpsSendBuf == NULL) return (-1); bzero (dhcpsSendBuf, sbufsize); pSendBuf = &dhcpsSendBuf [DHCPS_OFF]; sbufvec[0].iov_len = ETHERHL + IPHL + UDPHL + DFLTDHCPLEN; sbufvec[0].iov_base = pSendBuf; dhcpsMsgOut.ether = (struct ether_header *)pSendBuf; dhcpsMsgOut.ip = (struct ip *)&pSendBuf [ETHERHL]; dhcpsMsgOut.udp = (struct udphdr *)&pSendBuf [ETHERHL + IPHL]; dhcpsMsgOut.dhcp = (struct dhcp *)&pSendBuf [ETHERHL + IPHL + UDPHL]; sbufvec[1].iov_base = dhcpsOverflowBuf; sbufvec[1].iov_len = 0; /* Contains length of bytes in use, not size. */ return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -