📄 dhcpc_subr.c
字号:
/* set default route, if router IP address is available. */ if (ISSET(param->got_option, _DHCP_ROUTER_TAG) && param->router != NULL && param->router->addr != NULL) {#if BSD<44 bzero ( (char *)&rt, sizeof (struct rtentry));#else bzero ( (char *)&rt, sizeof (struct ortentry));#endif bzero ( (char *)&dst, sizeof (struct sockaddr)); bzero ( (char *)&gateway, sizeof (struct sockaddr)); rt.rt_flags = RTF_UP | RTF_GATEWAY; ( (struct sockaddr_in *)&dst)->sin_family = AF_INET; ( (struct sockaddr_in *)&dst)->sin_len = sizeof (struct sockaddr_in); ( (struct sockaddr_in *)&dst)->sin_addr.s_addr = INADDR_ANY; ( (struct sockaddr_in *)&gateway)->sin_family = AF_INET; ( (struct sockaddr_in *)&gateway)->sin_len = sizeof (struct sockaddr_in); ( (struct sockaddr_in *)&gateway)->sin_addr.s_addr = param->router->addr->s_addr; rt.rt_dst = dst; rt.rt_gateway = gateway; if (ioctl (sockfd, SIOCADDRT, (int)&rt) < 0) {#ifdef DHCPC_DEBUG logMsg ("SIOCADDRT (default route)\n", 0, 0, 0, 0, 0, 0);#endif close (sockfd); } } close (sockfd); return; }/********************************************************************************* make_decline - construct a DHCP decline message** This routine constructs an outgoing UDP/IP message containing the values* required to decline an offered IP address.** RETURNS: size of decline message, or 0 if error** ERRNO: N/A** NOMANUAL*/int make_decline ( struct dhcp_reqspec *pReqSpec, struct if_info * pIfData /* interface used by lease */ ) { int offopt = 0; /* offset in options field */ int msgsize; /* total size of DHCP message */ u_long tmpul = 0; struct ps_udph pudph; bzero ( (char *)&pudph, sizeof (pudph)); /* construct dhcp part */ bzero (sbuf.buf, sbuf.size); dhcpcMsgOut.dhcp->op = BOOTREQUEST; dhcpcMsgOut.dhcp->htype = pIfData->haddr.htype; dhcpcMsgOut.dhcp->hlen = pIfData->haddr.hlen; dhcpcMsgOut.dhcp->xid = htonl (generate_xid (pIfData)); dhcpcMsgOut.dhcp->giaddr = dhcpcMsgIn.dhcp->giaddr; bcopy (pIfData->haddr.haddr, dhcpcMsgOut.dhcp->chaddr, dhcpcMsgOut.dhcp->hlen); /* insert magic cookie */ bcopy ( (char *)dhcpCookie, dhcpcMsgOut.dhcp->options, MAGIC_LEN); offopt = MAGIC_LEN; /* insert message type */ dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_MSGTYPE_TAG; dhcpcMsgOut.dhcp->options [offopt++] = 1; dhcpcMsgOut.dhcp->options [offopt++] = DHCPDECLINE; /* insert requested IP */ if (pReqSpec->ipaddr.s_addr == 0) return (0); dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_REQUEST_IPADDR_TAG; dhcpcMsgOut.dhcp->options [offopt++] = 4; bcopy ( (char *)&pReqSpec->ipaddr, &dhcpcMsgOut.dhcp->options [offopt], 4); offopt += 4; /* insert client identifier */ if (pReqSpec->clid != NULL) { dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_CLIENT_ID_TAG; dhcpcMsgOut.dhcp->options [offopt++] = pReqSpec->clid->len; bcopy (pReqSpec->clid->id, &dhcpcMsgOut.dhcp->options [offopt], pReqSpec->clid->len); offopt += pReqSpec->clid->len; } /* insert server identifier */ dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_SERVER_ID_TAG; dhcpcMsgOut.dhcp->options [offopt++] = 4; bcopy ( (char *)&pReqSpec->srvaddr, &dhcpcMsgOut.dhcp->options [offopt], 4); offopt += 4; /* Insert error message, if available. */ if (pReqSpec->dhcp_errmsg != NULL) { dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_ERRMSG_TAG; dhcpcMsgOut.dhcp->options [offopt++] = strlen (pReqSpec->dhcp_errmsg); bcopy (pReqSpec->dhcp_errmsg, &dhcpcMsgOut.dhcp->options [offopt], strlen (pReqSpec->dhcp_errmsg)); offopt += strlen (pReqSpec->dhcp_errmsg); } dhcpcMsgOut.dhcp->options [offopt] = _DHCP_END_TAG; /* * For backward compatibility with earlier DHCP servers, set the * reported message size to be at least as large as a BOOTP message. */ msgsize = (DFLTDHCPLEN - DFLTOPTLEN) + offopt + 1; if (msgsize < DFLTBOOTPLEN) msgsize = DFLTBOOTPLEN; /* construct udp part */ dhcpcMsgOut.udp->uh_sport = dhcpc_port; dhcpcMsgOut.udp->uh_dport = dhcps_port; dhcpcMsgOut.udp->uh_ulen = htons (msgsize + UDPHL); dhcpcMsgOut.udp->uh_sum = 0; /* fill pseudo udp header */ pudph.srcip.s_addr = 0; pudph.dstip.s_addr = pReqSpec->srvaddr.s_addr; pudph.zero = 0; pudph.prto = IPPROTO_UDP; pudph.ulen = dhcpcMsgOut.udp->uh_ulen; dhcpcMsgOut.udp->uh_sum = udp_cksum (&pudph, (char *)dhcpcMsgOut.udp, ntohs (pudph.ulen)); /* construct ip part */#if BSD<44 dhcpcMsgOut.ip->ip_v_hl = 0; dhcpcMsgOut.ip->ip_v_hl = IPVERSION << 4; dhcpcMsgOut.ip->ip_v_hl |= IPHL >> 2;#else dhcpcMsgOut.ip->ip_v = IPVERSION; dhcpcMsgOut.ip->ip_hl = IPHL >> 2;#endif dhcpcMsgOut.ip->ip_tos = 0; dhcpcMsgOut.ip->ip_len = htons (msgsize + UDPHL + IPHL); tmpul = generate_xid (pIfData); tmpul += (tmpul >> 16); dhcpcMsgOut.ip->ip_id = (u_short) (~tmpul); dhcpcMsgOut.ip->ip_off = htons(IP_DF); /* XXX */ dhcpcMsgOut.ip->ip_ttl = 0x20; /* XXX */ dhcpcMsgOut.ip->ip_p = IPPROTO_UDP; msgsize += UDPHL + IPHL; dhcpcMsgOut.ip->ip_src.s_addr = 0; dhcpcMsgOut.ip->ip_dst.s_addr = INADDR_BROADCAST; dhcpcMsgOut.ip->ip_sum = 0;#if BSD<44 dhcpcMsgOut.ip->ip_sum = checksum ( (u_short *)dhcpcMsgOut.ip, (dhcpcMsgOut.ip->ip_v_hl & 0xf) << 2);#else dhcpcMsgOut.ip->ip_sum = checksum ( (u_short *)dhcpcMsgOut.ip, dhcpcMsgOut.ip->ip_hl << 2);#endif return (msgsize); }/********************************************************************************* 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: Size of DHCP message, in bytes** ERRNO: N/A** NOMANUAL*/int make_release ( struct dhcp_reqspec *pReqSpec, struct if_info * pIfData, /* interface used by lease */ BOOL oldFlag /* Use older (padded) DHCP message format? */ ) { int offopt = 0; /* offset in options field */ int msgsize; /* construct dhcp part */ bzero (sbuf.buf, sbuf.size); dhcpcMsgOut.dhcp->op = BOOTREQUEST; dhcpcMsgOut.dhcp->htype = pIfData->haddr.htype; dhcpcMsgOut.dhcp->hlen = pIfData->haddr.hlen; dhcpcMsgOut.dhcp->xid = htonl (generate_xid (pIfData)); dhcpcMsgOut.dhcp->ciaddr = pReqSpec->ipaddr; bcopy (pIfData->haddr.haddr, dhcpcMsgOut.dhcp->chaddr, dhcpcMsgOut.dhcp->hlen); /* insert magic cookie */ bcopy ( (char *)dhcpCookie, dhcpcMsgOut.dhcp->options, MAGIC_LEN); offopt = MAGIC_LEN; /* insert message type */ dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_MSGTYPE_TAG; dhcpcMsgOut.dhcp->options [offopt++] = 1; dhcpcMsgOut.dhcp->options [offopt++] = DHCPRELEASE; /* insert client identifier */ if (pReqSpec->clid != NULL) { dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_CLIENT_ID_TAG; dhcpcMsgOut.dhcp->options [offopt++] = pReqSpec->clid->len; bcopy (pReqSpec->clid->id, &dhcpcMsgOut.dhcp->options [offopt], pReqSpec->clid->len); offopt += pReqSpec->clid->len; } /* insert server identifier */ dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_SERVER_ID_TAG; dhcpcMsgOut.dhcp->options [offopt++] = 4; bcopy ( (char *)&pReqSpec->srvaddr, &dhcpcMsgOut.dhcp->options [offopt], 4); offopt += 4; /* Insert error message, if available. */ if (pReqSpec->dhcp_errmsg != NULL) { dhcpcMsgOut.dhcp->options [offopt++] = _DHCP_ERRMSG_TAG; dhcpcMsgOut.dhcp->options [offopt++] = strlen (pReqSpec->dhcp_errmsg); bcopy (pReqSpec->dhcp_errmsg, &dhcpcMsgOut.dhcp->options [offopt], strlen (pReqSpec->dhcp_errmsg)); offopt += strlen (pReqSpec->dhcp_errmsg); } dhcpcMsgOut.dhcp->options [offopt] = _DHCP_END_TAG; msgsize = (DFLTDHCPLEN - DFLTOPTLEN) + offopt + 1; if (oldFlag) { /* * This flag indicates that the client did not receive a response * to the initial set of discover messages but did receive one * using the older message format. The (older) responding server * ignores messages less than the minimum length obtained with a * fixed options field, so pad the message to reach that length. */ if (msgsize < DFLTDHCPLEN) msgsize = DFLTDHCPLEN; } return (msgsize); }/********************************************************************************* 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 */ ) { struct sockaddr_in dest; /* Server's destination address */ struct ifnet * pIf; /* Transmit device */ int length; /* Amount of data in message */#ifdef DHCPC_DEBUG char output [INET_ADDR_LEN];#endif if (pDhcpcReqSpec->srvaddr.s_addr == 0) return(-1); length = make_decline (pDhcpcReqSpec, pIfData); if (length == 0) return (-1); bzero ( (char *)&dest, sizeof (struct sockaddr_in)); dest.sin_len = sizeof (struct sockaddr_in); dest.sin_family = AF_INET; dest.sin_addr.s_addr = INADDR_BROADCAST; pIf = pIfData->iface; if (dhcpSend (pIf, &dest, sbuf.buf, length, TRUE) == ERROR) {#ifdef DHCPC_DEBUG logMsg ("Can't send DHCPDECLINE.\n", 0, 0, 0, 0, 0, 0);#endif return (-1); }#ifdef DHCPC_DEBUG inet_ntoa_b (pDhcpcReqSpec->ipaddr, output); logMsg ("send DHCPDECLINE(%s)\n", (int)output, 0, 0, 0, 0, 0);#endif 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 */ BOOL oldFlag /* Use older (padded) DHCP message format? */ ) {#ifdef DHCPC_DEBUG char output [INET_ADDR_LEN];#endif int length; if (pDhcpcReqSpec->srvaddr.s_addr == 0) return (-1); /* send DHCP message */ length = make_release (pDhcpcReqSpec, pIfData, oldFlag); if (send_unicast (&pDhcpcReqSpec->srvaddr, dhcpcMsgOut.dhcp, length) < 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); }/********************************************************************************* dhcpcPrivateCleanup - remove data structures from client library** The dhcpcCleanup routine uses this routine to release the locally* allocated data structures which the initialize() call creates. It is* part of the shutdown process for the DHCP client library. The routine* executes after all leases are inactive and their data is released.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void dhcpcPrivateCleanup (void) { /* Close open file and remove BPF device for ARP probe. */ close (bpfArpDev); bpfDevDelete ("/bpf/dhcpc-arp"); /* Release transmission buffer. */ free (sbuf.buf); return; } /********************************************************************************* set_declinfo - initialize request specification for decline message** This routine assigns the fields in the reques
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -