📄 dhcpc_subr.c
字号:
{ lsdhcp->options [offopt++] = _DHCP_REQUEST_IPADDR_TAG; lsdhcp->options [offopt++] = 4; bcopy ( (char *)&pDhcpcReqSpec->ipaddr, &lsdhcp->options [offopt], 4); offopt += 4; } /* insert client identifier */ if (pDhcpcReqSpec->clid != NULL && CHKOFF (pDhcpcReqSpec->clid->len + 1)) { lsdhcp->options [offopt++] = _DHCP_CLIENT_ID_TAG; lsdhcp->options [offopt++] = pDhcpcReqSpec->clid->len + 1; lsdhcp->options [offopt++] = pDhcpcReqSpec->clid->type; bcopy (pDhcpcReqSpec->clid->id, &lsdhcp->options [offopt], pDhcpcReqSpec->clid->len); offopt += pDhcpcReqSpec->clid->len; } /* insert server identifier */ if (CHKOFF (4)) { lsdhcp->options [offopt++] = _DHCP_SERVER_ID_TAG; lsdhcp->options [offopt++] = 4; bcopy ( (char *)&pDhcpcReqSpec->srvaddr, &lsdhcp->options [offopt], 4); offopt += 4; } /* if necessary, insert error message */ if (pDhcpcReqSpec->dhcp_errmsg != NULL && CHKOFF (strlen (pDhcpcReqSpec->dhcp_errmsg))) { lsdhcp->options [offopt++] = _DHCP_ERRMSG_TAG; lsdhcp->options [offopt++] = strlen (pDhcpcReqSpec->dhcp_errmsg); bcopy (pDhcpcReqSpec->dhcp_errmsg, &lsdhcp->options [offopt], strlen (pDhcpcReqSpec->dhcp_errmsg)); offopt += strlen (pDhcpcReqSpec->dhcp_errmsg); } lsdhcp->options [offopt] = _DHCP_END_TAG; /* construct udp part */ lsudp->uh_sport = dhcpc_port; lsudp->uh_dport = dhcps_port; lsudp->uh_ulen = htons (DFLTDHCPLEN + UDPHL); lsudp->uh_sum = 0; /* fill pseudo udp header */ pudph.srcip.s_addr = 0; pudph.dstip.s_addr = pDhcpcReqSpec->srvaddr.s_addr; pudph.zero = 0; pudph.prto = IPPROTO_UDP; pudph.ulen = lsudp->uh_ulen; lsudp->uh_sum = udp_cksum(&pudph, (char *) lsudp, ntohs(pudph.ulen)); /* construct ip part */#if BSD<44 lsip->ip_v_hl = 0; lsip->ip_v_hl = IPVERSION << 4; lsip->ip_v_hl |= IPHL >> 2;#else lsip->ip_v = IPVERSION; lsip->ip_hl = IPHL >> 2;#endif lsip->ip_tos = 0; lsip->ip_len = htons(DFLTDHCPLEN + UDPHL + IPHL); tmpul = generate_xid (pIfData); tmpul += (tmpul >> 16); lsip->ip_id = (u_short) (~tmpul); lsip->ip_off = htons(IP_DF); /* XXX */ lsip->ip_ttl = 0x20; /* XXX */ lsip->ip_p = IPPROTO_UDP; lsip->ip_src.s_addr = 0; lsip->ip_dst.s_addr = dhcpcMsgIn.ip->ip_src.s_addr; lsip->ip_sum = 0;#if BSD<44 lsip->ip_sum = checksum((u_short *)lsip, (lsip->ip_v_hl & 0xf) << 2);#else lsip->ip_sum = checksum((u_short *)lsip, lsip->ip_hl << 2);#endif /* construct ether part */ for (i = 0; i < 6; i++) { lsether->ether_dhost[i] = dhcpcMsgIn.ether->ether_shost[i]; lsether->ether_shost[i] = pIfData->haddr.haddr[i]; } lsether->ether_type = ETHERTYPE_IP; return; }/********************************************************************************* make_release - construct a DHCP release message** This routine constructs an outgoing UDP/IP message containing the values* required to relinquish the active lease.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void make_release ( struct dhcp *lsdhcp, struct dhcp_reqspec *pDhcpcReqSpec, struct if_info * pIfData /* interface used by lease */ ) { int offopt = 0; /* offset in options field */ /* construct dhcp part */ lsdhcp->op = BOOTREQUEST; lsdhcp->htype = pIfData->haddr.htype; lsdhcp->hlen = pIfData->haddr.hlen; lsdhcp->xid = generate_xid (pIfData); lsdhcp->ciaddr = pDhcpcReqSpec->ipaddr; bcopy (pIfData->haddr.haddr, lsdhcp->chaddr, lsdhcp->hlen); /* insert magic cookie */ bcopy ( (char *)dhcpCookie, lsdhcp->options, MAGIC_LEN); offopt = MAGIC_LEN; /* insert message type */ lsdhcp->options [offopt++] = _DHCP_MSGTYPE_TAG; lsdhcp->options [offopt++] = 1; lsdhcp->options [offopt++] = DHCPRELEASE; /* insert server identifier */ if (CHKOFF (4)) { lsdhcp->options [offopt++] = _DHCP_SERVER_ID_TAG; lsdhcp->options [offopt++] = 4; bcopy ( (char *)&pDhcpcReqSpec->srvaddr, &lsdhcp->options [offopt], 4); offopt += 4; } /* insert client identifier */ if (pDhcpcReqSpec->clid != NULL && CHKOFF (pDhcpcReqSpec->clid->len + 1)) { lsdhcp->options [offopt++] = _DHCP_CLIENT_ID_TAG; lsdhcp->options [offopt++] = pDhcpcReqSpec->clid->len + 1; lsdhcp->options [offopt++] = pDhcpcReqSpec->clid->type; bcopy (pDhcpcReqSpec->clid->id, &lsdhcp->options [offopt], pDhcpcReqSpec->clid->len); offopt += pDhcpcReqSpec->clid->len; } /* if necessary, insert error message */ if (pDhcpcReqSpec->dhcp_errmsg != NULL && CHKOFF (strlen (pDhcpcReqSpec->dhcp_errmsg))) { lsdhcp->options [offopt++] = _DHCP_ERRMSG_TAG; lsdhcp->options [offopt++] = strlen (pDhcpcReqSpec->dhcp_errmsg); bcopy(pDhcpcReqSpec->dhcp_errmsg, &lsdhcp->options [offopt], strlen (pDhcpcReqSpec->dhcp_errmsg)); offopt += strlen (pDhcpcReqSpec->dhcp_errmsg); } lsdhcp->options [offopt] = _DHCP_END_TAG; return; }/********************************************************************************* dhcp_decline - send a DHCP decline message** This routine constructs a message declining an offered IP address and sends* it directly to the responding server. It is called when an ARP request * detects that the offered address is already in use.** RETURNS: 0 if message sent, or -1 on error.** ERRNO: N/A** NOMANUAL*/int dhcp_decline ( struct dhcp_reqspec * pDhcpcReqSpec, struct if_info * pIfData /* interface used by lease */ ) { int lsbufsize = ETHERHL + IPHL + UDPHL + DFLTDHCPLEN; char *lsbuf; char *lsbufp;#ifdef DHCPC_DEBUG char output [INET_ADDR_LEN];#endif if (pDhcpcReqSpec->srvaddr.s_addr == 0) return(-1); /* * Allocate clean memory and build new DHCP message. Use offset to * provide 4-byte alignment of IP header needed by Sun BSP's. */ lsbuf = (char *)memalign (4, DHCPC_OFF + lsbufsize); if (lsbuf == NULL) return (-1); bzero (lsbuf, lsbufsize + DHCPC_OFF); lsbufp = &lsbuf [DHCPC_OFF]; bzero (lsbufp, lsbufsize); make_decline (lsbufp, pDhcpcReqSpec, pIfData); if (etherOutput (pIfData->iface, (struct ether_header *)lsbufp, &lsbufp [ETHERHL], lsbufsize - ETHERHL) == ERROR) { free (lsbuf); return (-1); }#ifdef DHCPC_DEBUG inet_ntoa_b (pDhcpcReqSpec->ipaddr, output); logMsg ("send DHCPDECLINE(%s)\n", (int)output, 0, 0, 0, 0, 0);#endif free (lsbuf); return (0); }/********************************************************************************* dhcp_release - send a DHCP release message** This routine constructs a message declining an offered IP address and sends* it directly to the responding server. It is called when an error prevents* the use of an acquired lease, or when the lease is relinquished manually* by a dhcpcRelease() or dhcpcShutdown() call. The message is sent directly to * the responding DHCP server.** RETURNS: 0 if message sent, or -1 on error.** ERRNO: N/A** NOMANUAL*/int dhcp_release ( struct dhcp_reqspec *pDhcpcReqSpec, struct if_info * pIfData /* interface used by lease */ ) { int lsbufsize = DFLTDHCPLEN; char lsbuf [DFLTDHCPLEN]; struct dhcp *lsdhcp = NULL;#ifdef DHCPC_DEBUG char output [INET_ADDR_LEN];#endif bzero (lsbuf, lsbufsize); lsdhcp = (struct dhcp *)lsbuf; if (pDhcpcReqSpec->srvaddr.s_addr == 0) return (-1); /* send DHCP message */ make_release (lsdhcp, pDhcpcReqSpec, pIfData); if (send_unicast (&pDhcpcReqSpec->srvaddr, lsdhcp) < 0) return (-1);#ifdef DHCPC_DEBUG inet_ntoa_b (pDhcpcReqSpec->ipaddr, output); logMsg("send DHCPRELEASE(%s)\n", (int)output, 0, 0, 0, 0, 0);#endif return(0); }/********************************************************************************* set_declinfo - initialize request specification for decline message** This routine assigns the fields in the request specifier used to construct* messages to the appropriate values for a DHCP decline message according to* the parameters of the currently active lease.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void set_declinfo ( struct dhcp_reqspec *pDhcpcReqSpec, LEASE_DATA * pLeaseData, char *errmsg, int arpans ) { char output [INET_ADDR_LEN]; struct dhcp_param * paramp; paramp = pLeaseData->dhcpcParam; pDhcpcReqSpec->ipaddr = paramp->yiaddr; pDhcpcReqSpec->srvaddr = paramp->server_id; if (pLeaseData->leaseReqSpec.clid != NULL) pDhcpcReqSpec->clid = pLeaseData->leaseReqSpec.clid; else pDhcpcReqSpec->clid = NULL; if (errmsg[0] == 0) { inet_ntoa_b (paramp->yiaddr, output); if (arpans != OK) sprintf (errmsg, "IP address (%s) is already in use.", output); else sprintf (errmsg, "IP address (%s) doesn't match requested value.", output); } pDhcpcReqSpec->dhcp_errmsg = errmsg; return; }/********************************************************************************* set_relinfo - initialize request specification for release message** This routine assigns the fields in the request specifier used to construct* messages to the appropriate values for a DHCP release message according to* the parameters of the currently active lease.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void set_relinfo ( struct dhcp_reqspec *pDhcpcReqSpec, LEASE_DATA * pLeaseData, char *errmsg ) { char output [INET_ADDR_LEN]; struct dhcp_param *paramp; paramp = pLeaseData->dhcpcParam; pDhcpcReqSpec->ipaddr.s_addr = paramp->yiaddr.s_addr; pDhcpcReqSpec->srvaddr.s_addr = paramp->server_id.s_addr; if (pLeaseData->leaseReqSpec.clid != NULL) pDhcpcReqSpec->clid = pLeaseData->leaseReqSpec.clid; else pDhcpcReqSpec->clid = NULL; if (pLeaseData->leaseReqSpec.dhcp_errmsg != NULL) pDhcpcReqSpec->dhcp_errmsg = pLeaseData->leaseReqSpec.dhcp_errmsg; else { inet_ntoa_b (paramp->yiaddr, output); sprintf (errmsg, "Releasing the current IP address (%s).", output); pDhcpcReqSpec->dhcp_errmsg = errmsg; } return; }/********************************************************************************* make_discover - construct a DHCP discover message** This routine constructs an outgoing UDP/IP message containing the values* required to broadcast a lease request. The <xidFlag> indicates whether* a transaction ID should be generated. Because multiple leases are supported,* the contents of the transmit buffer are not guaranteed to remain unchanged.* Therefore, each message must be rebuilt before it is sent. However, the* transaction ID must not be changed after the initial transmission.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void make_discover ( LEASE_DATA * pLeaseData, /* lease-specific data structures */ BOOL xidFlag /* generate a new transaction ID? */ ) { int i = 0; int offopt = 0; /* offset in options field */ u_long tmpul = 0; u_short tmpus = 0; struct dhcp_reqspec * pReqSpec; pReqSpec = &pLeaseData->leaseReqSpec; /* construct dhcp part */ bzero (sbuf.buf, sbuf.size + DHCPC_OFF); dhcpcMsgOut.dhcp->op = BOOTREQUEST; dhcpcMsgOut.dhcp->htype = pLeaseData->ifData.haddr.htype; dhcpcMsgOut.dhcp->hlen = pLeaseData->ifData.haddr.hlen; if (xidFlag) pLeaseData->xid = generate_xid (&pLeaseData->ifData); dhcpcMsgOut.dhcp->xid = pLeaseData->xid; bcopy (pLeaseData->ifData.haddr.haddr, dhcpcMsgOut.dhcp->chaddr, dhcpcMsgOut.dhcp->hlen); /* insert magic cookie */ bcopy ( (char *)dhcp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -