📄 bootplib.c
字号:
* RFC 1533 using the following definition:** .CS* struct bootpParams* {* struct in_addr * netmask;* unsigned short * timeOffset;* struct in_addr_list * routers;* struct in_addr_list * timeServers;* struct in_addr_list * nameServers;* struct in_addr_list * dnsServers;* struct in_addr_list * logServers;* struct in_addr_list * cookieServers;* struct in_addr_list * lprServers;* struct in_addr_list * impressServers;* struct in_addr_list * rlpServers;* char * clientName;* unsigned short * filesize;* char * dumpfile;* char * domainName;* struct in_addr * swapServer;* char * rootPath;* char * extoptPath;* unsigned char * ipForward;* unsigned char * nonlocalSourceRoute;* struct in_addr_list * policyFilter;* unsigned short * maxDgramSize;* unsigned char * ipTTL;* unsigned long * mtuTimeout;* struct ushort_list * mtuTable;* unsigned short * intfaceMTU;* unsigned char * allSubnetsLocal;* struct in_addr * broadcastAddr;* unsigned char * maskDiscover;* unsigned char * maskSupplier;* unsigned char * routerDiscover;* struct in_addr * routerDiscAddr;* struct in_addr_list * staticRoutes;* unsigned char * arpTrailers;* unsigned long * arpTimeout;* unsigned char * etherPacketType;* unsigned char * tcpTTL;* unsigned long * tcpInterval;* unsigned char * tcpGarbage;* char * nisDomain;* struct in_addr_list * nisServers;* struct in_addr_list * ntpServers;* char * vendString;* struct in_addr_list * nbnServers;* struct in_addr_list * nbddServers;* unsigned char * nbNodeType;* char * nbScope;* struct in_addr_list * xFontServers;* struct in_addr_list * xDisplayManagers;* char * nispDomain;* struct in_addr_list * nispServers;* struct in_addr_list * ipAgents;* struct in_addr_list * smtpServers;* struct in_addr_list * pop3Servers;* struct in_addr_list * nntpServers;* struct in_addr_list * wwwServers;* struct in_addr_list * fingerServers;* struct in_addr_list * ircServers;* struct in_addr_list * stServers;* struct in_addr_list * stdaServers; * };* .CE** This structure allows the retrieval of any BOOTP option specified in* RFC 1533. The list of 2-byte (unsigned short) values is defined as:** .CS* struct ushort_list* {* unsigned char num;* unsigned short * shortlist;* };* .CE** The IP address lists use the following similar definition:** .CS* struct in_addr_list* {* unsigned char num;* struct in_addr * addrlist;* };* .CE** When these lists are present, the routine stores values retrieved from* the BOOTP reply in the location indicated by the `shortlist' or `addrlist'* members. The amount of space available is indicated by the `num' member.* When the routine returns, the `num' member indicates the actual number of* entries retrieved. In the case of `bootpParams.policyFilter.num' * and `bootpParams.staticRoutes.num', the `num' member value should be * interpreted as the number of IP address pairs requested and received.** .LP* The contents of the BOOTP parameter descriptor implicitly selects options* for retrieval from the BOOTP server. This routine attempts to retrieve the* values for any options whose corresponding field pointers are non-NULL* values. To obtain these parameters, the BOOTP server must support the* vendor-specific options described in RFC 1048 (or its successors) and the * corresponding parameters must be specified in the BOOTP server database. * Where meaningful, the values are returned in host byte order. ** The BOOTP request issued during system startup with this routine attempts* to retrieve a subnet mask for the boot device, in addition to the host and* client addresses and the boot file name.** RETURNS: OK, or ERROR if unsuccessful.** SEE ALSO: bootLib, RFC 1048, RFC 1533*/STATUS bootpParamsGet ( struct ifnet * pIf, /* network device used by client */ u_int maxSends, /* maximum transmit attempts */ struct in_addr * pClientAddr, /* retrieved client address buffer */ struct in_addr * pServerAddr, /* buffer for server's IP address */ char * pHostName, /* 64 byte (max) host name buffer */ char * pBootFile, /* 128 byte (max) file name buffer */ struct bootpParams * pBootpParams /* parameters descriptor */ ) { BOOTP_MSG bootpMessage; /* bootp message */ struct in_addr ipDest; /* ip dest address */ int length; int htype; int maxSize; /* Largest BOOTP message available from BPF device. */ if (!bootpInitialized) { errno = S_bootpLib_NOT_INITIALIZED; return (ERROR); } if (pIf == NULL) { errno = S_bootpLib_BAD_DEVICE; return (ERROR); } if (muxDevExists (pIf->if_name, pIf->if_unit) == FALSE) { errno = S_bootpLib_BAD_DEVICE; return (ERROR); } /* Verify interface data sizes are appropriate for message. */ if (pIf->if_mtu == 0) { errno = S_bootpLib_BAD_DEVICE; return (ERROR); } length = pIf->if_mtu; if (length < BOOTPLEN + UDPHL + IPHL) { /* * Devices must accept messages equal to an IP datagram * of 328 bytes, which corresponds to the fixed-size BOOTP * message with the minimum headers. */ errno = S_bootpLib_BAD_DEVICE; return (ERROR); } length = pIf->if_hdrlen + BOOTPLEN + UDPHL + IPHL; maxSize = bootpBufSize - sizeof (struct bpf_hdr); if (length > maxSize) { /* Link level header exceeds maximum supported value. */ errno = S_bootpLib_BAD_DEVICE; return (ERROR); } htype = bootpConvert (pIf->if_type); if (htype == ERROR) { /* Unknown device type. Can't encode with RFC 1700 value. */ errno = S_bootpLib_BAD_DEVICE; return (ERROR); } /* Fill in BOOTP request message. */ bzero ((char *) &bootpMessage, sizeof (BOOTP_MSG)); bootpMessage.bp_op = BOOTREQUEST; bootpMessage.bp_htype = htype; bootpMessage.bp_hlen = pIf->if_addrlen; if (bootpMessage.bp_hlen > SIZE_HLEN) bootpMessage.bp_hlen = SIZE_HLEN; bcopy ( (char *) ( (struct arpcom *)pIf)->ac_enaddr, bootpMessage.bp_chaddr, bootpMessage.bp_hlen); /* Check for specific boot host name. */ if (pHostName != NULL) { length = strlen (pHostName); if (length >= SIZE_SNAME) /* Leave space for EOS character. */ length = SIZE_SNAME - 1; (void) strncpy ( (char *) bootpMessage.bp_sname, pHostName, length); } /* Check for partial boot file. */ if (pBootFile != NULL) { length = strlen (pBootFile); if (length >= SIZE_FILE) /* Leave space for EOS character. */ length = SIZE_FILE - 1; (void) strncpy ( (char *) bootpMessage.bp_file, pBootFile, length); } /* Fill in RFC 1048 magic cookie. */ bcopy ( (char *) magicCookie1048, (char *) bootpMessage.bp_vend, sizeof (magicCookie1048)); bcopy ( (char *) endOfVend, (char *) bootpMessage.bp_vend + sizeof(magicCookie1048), sizeof(endOfVend)); /* Check for specific BOOTP server's IP address, or use broadcast. */ if (pServerAddr == NULL || pServerAddr->s_addr == 0) ipDest.s_addr = INADDR_BROADCAST; else ipDest.s_addr = pServerAddr->s_addr; /* Send BOOTP request and retrieve reply using the reserved ports. */ if (bootpMsgGet (pIf, &ipDest, _BOOTP_CPORT, _BOOTP_SPORT, &bootpMessage, maxSends) == ERROR) return (ERROR); /* Fill in any entries requested by user and provided by server. */ bootpParamsFill (pClientAddr, pServerAddr, pHostName, pBootFile, pBootpParams, &bootpMessage); return (OK); }/******************************************************************************** bootpParamsFill - copy requested BOOTP options** This routine fills in the non-NULL fields in the given parameter descriptor* with the corresponding entries from the received BOOTP message. It is only* called internally after bootpMsgGet() completes successfully.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/LOCAL void bootpParamsFill ( struct in_addr * pClientAddr, /* buffer for client address */ struct in_addr * pServerAddr, /* buffer for server's IP address */ char * pHostName, /* 64 byte (max) host name buffer */ char * pBootFile, /* 128 byte (max) file name buffer */ struct bootpParams * pBootpParams, /* parameters descriptor */ BOOTP_MSG * pBootpReply /* reply from BOOTP server */ ) { int loop; int limit; u_char * cp; int length; int number; /* Copy entries from message body if requested by user. */ /* Fill in assigned IP address. */ if (pClientAddr != NULL) *pClientAddr = pBootpReply->bp_yiaddr; /* Fill in boot server's IP address. */ if (pServerAddr != NULL) *pServerAddr = pBootpReply->bp_siaddr; /* Fill in boot file. */ if (pBootFile != NULL) { if (pBootpReply->bp_file [0] == EOS) { pBootFile[0] = EOS; } else strcpy (pBootFile, (char *)pBootpReply->bp_file); } /* Fill in server name. */ if (pHostName != NULL) { if (pBootpReply->bp_sname[0] == EOS) pHostName[0] = EOS; else strcpy (pHostName, pBootpReply->bp_sname); } /* Fill in optional entries requested by user, if present in reply. */ /* Retrieve subnet mask. */ if (pBootpParams->netmask != NULL) { length = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_SUBNET_MASK, &length); if (cp != NULL) bcopy ( (char *) cp, (char *)pBootpParams->netmask, length); else bzero ( (char *)pBootpParams->netmask, sizeof (struct in_addr)); } /* Retrieve time offset. */ if (pBootpParams->timeOffset != NULL) { length = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_TIME_OFFSET, &length); if (cp != NULL) *pBootpParams->timeOffset = ntohs (*(unsigned short *)cp); else *pBootpParams->timeOffset = 0; } /* Retrieve IP addresses of IP routers, up to number requested. */ if (pBootpParams->routers != NULL && pBootpParams->routers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_GATEWAY, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->routers->num < number) ? pBootpParams->routers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->routers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->routers->num = limit; } /* Retrieve IP addresses of time servers, up to number requested. */ if (pBootpParams->timeServers != NULL && pBootpParams->timeServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_TIME_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -