📄 bootplib.c
字号:
cp = bootpTagFind (pBootpReply->bp_vend, TAG_NISP_DOMAIN, &length); if (cp != NULL) { bcopy ( (char *)cp, pBootpParams->nispDomain, length); pBootpParams->nispDomain [length] = EOS; } else pBootpParams->nispDomain[0] = EOS; } /* Retrieve IP addresses of NIS+ servers. */ if (pBootpParams->nispServers != NULL && pBootpParams->nispServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_NISP_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->nispServers->num < number) ? pBootpParams->nispServers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->nispServers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->nispServers->num = limit; } /* Retrieve IP addresses of Mobile IP Home Agents. */ if (pBootpParams->ipAgents != NULL && pBootpParams->ipAgents->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_MOBILEIP_HA, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->ipAgents->num < number) ? pBootpParams->ipAgents->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->ipAgents->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->ipAgents->num = limit; } /* Retrieve IP addresses of SMTP servers. */ if (pBootpParams->smtpServers != NULL && pBootpParams->smtpServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_SMTP_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->smtpServers->num < number) ? pBootpParams->smtpServers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->smtpServers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->smtpServers->num = limit; } /* Retrieve IP addresses of POP3 servers. */ if (pBootpParams->pop3Servers != NULL && pBootpParams->pop3Servers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_POP3_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->pop3Servers->num < number) ? pBootpParams->pop3Servers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->pop3Servers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->pop3Servers->num = limit; } /* Retrieve IP addresses of NNTP servers. */ if (pBootpParams->nntpServers != NULL && pBootpParams->nntpServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_NNTP_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->nntpServers->num < number) ? pBootpParams->nntpServers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->nntpServers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->nntpServers->num = limit; } /* Retrieve IP addresses of World Wide Web servers. */ if (pBootpParams->wwwServers != NULL && pBootpParams->wwwServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_WWW_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->wwwServers->num < number) ? pBootpParams->wwwServers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->wwwServers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->wwwServers->num = limit; } /* Retrieve IP addresses of finger servers. */ if (pBootpParams->fingerServers != NULL && pBootpParams->fingerServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_FINGER_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->fingerServers->num < number) ? pBootpParams->fingerServers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->fingerServers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->fingerServers->num = limit; } /* Retrieve IP addresses of Internet Relay Chat servers. */ if (pBootpParams->ircServers != NULL && pBootpParams->ircServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_IRC_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->ircServers->num < number) ? pBootpParams->ircServers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->ircServers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->ircServers->num = limit; } /* Retrieve IP addresses of StreetTalk servers. */ if (pBootpParams->stServers != NULL && pBootpParams->stServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_ST_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->stServers->num < number) ? pBootpParams->stServers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->stServers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->stServers->num = limit; } /* Retrieve IP addresses of STDA servers. */ if (pBootpParams->stdaServers != NULL && pBootpParams->stdaServers->addrlist != NULL) { length = 0; limit = 0; cp = bootpTagFind (pBootpReply->bp_vend, TAG_STDA_SERVER, &length); if (cp != NULL) { number = length / sizeof (struct in_addr); limit = (pBootpParams->stdaServers->num < number) ? pBootpParams->stdaServers->num : number; for (loop = 0; loop < limit; loop++) { bcopy ( (char *)cp, (char *)&pBootpParams->stdaServers->addrlist[loop], sizeof (struct in_addr)); cp += sizeof (struct in_addr); } } pBootpParams->stdaServers->num = limit; } return; }/******************************************************************************** bootpMsgSend - send a BOOTP request message** This routine sends the BOOTP message indicated by <pBootpMsg> using the * network interface specified by <ifName>. The <pIpDest> argument specifies * the destination IP address. In most cases, the broadcast address* (255.255.255.255) is used. However, this parameter also accepts the IP* address of a particular BOOTP server. That server must reside on the* same subnet as the specified network interface.** A non-zero value for <port> specifies an alternate BOOTP server port.* Otherwise, the default port (67) is used.** This routine always sets the values of the `bp_op', `bp_xid', and `bp_secs' * members in the BOOTP message structure, but it allows the caller to assign * values to any of the other members. However, if the `bp_hlen' member is 0, * the routine uses the Ethernet address of the specified network interface * for the `bp_chaddr' member and sets `bp_type' to 1 and `bp_hlen' to 6 as * required for that address.** The bootpMsgSend() routine will retransmit the BOOTP message if it gets no* reply. The retransmission time increases exponentially but is bounded* by the number of ticks specified in the <timeOut> parameter. If no reply is* received within this period, an error is returned. A value of zero specifies* an infinite timeout value.** NOTE: If `bp_ciaddr' is specified, the BOOTP server may assume that the* client will respond to an ARP request.** RETURNS: OK, or ERROR.** ERRNO* S_bootpLib_INVALID_ARGUMENT* S_bootpLib_NO_BROADCASTS* S_bootpLib_TIME_OUT*/STATUS bootpMsgSend ( char * ifName, /* network interface name */ struct in_addr * pIpDest, /* destination IP address */ int port, /* port number */ BOOTP_MSG * pBootpMsg, /* pointer to BOOTP message */ u_int timeOut /* timeout in ticks */ ) { FAST int tickCount; /* tick counter */ FAST int tickStart; /* start of transmissions */ FAST int retransmitSecs; /* retransmission time */ int backOffTicks; /* semi random backoff time */ struct in_addr ipSrc; /* source */ struct ifnet * pIf; /* pointer to interface */ BOOL firstXmit = TRUE;/* first transmission */ END_OBJ * pEnd; if ((pBootpMsg == NULL) || ((pIf = ifunit (ifName)) == NULL)) /* validate args */ { errno = S_bootpLib_INVALID_ARGUMENT; return (ERROR); } pEnd = endFindByName (pIf->if_name, pIf->if_unit); /* if destination is a broadcast, then be sure the interface allows it */ if ( (in_broadcast (*pIpDest, pIf)) && ( (pIf->if_flags & IFF_BROADCAST) == 0)) { errno = S_bootpLib_NO_BROADCASTS; return (ERROR); } pIf->if_flags |= (IFF_UP | IFF_RUNNING); /* initialize values */ bootpReplyReceived = FALSE; tickStart = tickGet (); retransmitSecs = bootpReXmitSecs; /* if source is a broadcast then set address to zero */ ipSrc.s_addr = in_broadcast (pBootpMsg->bp_ciaddr, pIf) ? htons ((u_short) 0) : pBootpMsg->bp_ciaddr.s_addr; /* * generate a (semi) random backoff time between 1 & 5 seconds, then * convert it to ticks. */ backOffTicks = ( ( ( (struct arpcom *)pIf)->ac_enaddr [5] + ( (struct arpcom *)pIf)->ac_enaddr [4] + ( (struct arpcom *)pIf)->ac_enaddr [3]) % 5) * sysClkRateGet (); bzero ( (char *)&bootpMsg, sizeof (bootpMsg)); /* fill in BOOTP message */ bootpMsg.bp = *pBootpMsg; bootpMsg.bp.bp_op = BOOTREQUEST; /* operation */ bootpMsg.bp.bp_xid = tickGet (); /* transmission id */ /* If hardware len is 0, then use Ethernet address as hardware address. */ if (bootpMsg.bp.bp_hlen == 0) { bootpMsg.bp.bp_htype = ETHER_ADDR_TYPE; bootpMsg.bp.bp_hlen = ETHER_ADDR_LEN; bcopy ( (char *) ( (struct arpcom *)pIf)->ac_enaddr, (char *)bootpMsg.bp.bp_chaddr, ETHER_ADDR_LEN); } /* fill in the UDP header */ bootpMsg.uh.uh_sport = htons ((u_short) IPPORT_BOOTPC); bootpMsg.uh.uh_dport = (port == 0) ? htons ((u_short) IPPORT_BOOTPS) : htons ((u_short) port); bootpMsg.uh.uh_ulen = htons (sizeof (bootpMsg.uh) + sizeof (bootpMsg.bp)); bootpMsg.uh.uh_sum = 0; ipHeaderCreate (IPPROTO_UDP, &ipSrc, pIpDest, &bootpMsg.ih, sizeof (boo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -