📄 dhcprelay.c
字号:
( struct if_info *list, int dhcplen ) { int i, total; char devName [10]; struct if_info *ifp; int msgtype = 0; char *option = NULL; struct ifnet *pIf; STATUS result;#ifdef DHCPR_DEBUG char srcAddr [INET_ADDR_LEN]; char dstAddr [INET_ADDR_LEN];#endif if (dhcpMsgIn.dhcp->hops >= 17) /* RFC limits to 16 hops - ignore. */ return; ifp = list; while (ifp != NULL) { if (ifp->ipaddr.s_addr == dhcpMsgIn.dhcp->giaddr.s_addr) break; ifp = ifp->next; } if (ifp == NULL) { #ifdef DHCPR_DEBUG inet_ntoa_b (dhcpMsgIn.ip->ip_src, srcAddr); logMsg ("Warning: DHCP message from server(%s) has no interface.\n", srcAddr, 0, 0, 0, 0, 0);#endif return; } sprintf (devName, "%s%d", ifp->name, ifp->unit); pIf = ifunit (devName); if (pIf == NULL) {#ifdef DHCPR_DEBUG logMsg ("Warning: couldn't access network interface %s.\n", (int)ifp->name, 0, 0, 0, 0, 0);#endif return; } if ( (option = pickup_opt (dhcpMsgIn.dhcp, dhcplen, _DHCP_MSGTYPE_TAG)) != NULL) msgtype = *OPTBODY(option); /* There is already space for ETHER, IP, and UDP headers. */ dhcprMsgOut.dhcp = dhcpMsgIn.dhcp; dhcprMsgOut.udp = dhcpMsgIn.udp; dhcprMsgOut.ip = dhcpMsgIn.ip; dhcprMsgOut.ether = dhcpMsgIn.ether;#ifdef DHCPR_DEBUG logMsg ("Client relay: Headers found.\n", 0, 0, 0, 0, 0, 0);#endif if (dhcpMsgIn.dhcp->htype != ETHER || dhcpMsgIn.dhcp->hlen != 6) return;#ifdef DHCPR_DEBUG logMsg ("Setting parameters.\n", 0, 0, 0, 0, 0, 0);#endif if (ISBRDCST (dhcpMsgIn.dhcp->flags)) {#ifdef DHCPR_DEBUG logMsg ("Broadcasting reply.\n", 0, 0, 0, 0, 0, 0);#endif for (i = 0; i < 6; i++) { dhcprMsgOut.ether->ether_dhost[i] = 0xff; dhcprMsgOut.ether->ether_shost[i] = ifp->haddr[i]; } dhcprMsgOut.ip->ip_dst.s_addr = 0xffffffff; dhcprMsgOut.ip->ip_src.s_addr = ifp->ipaddr.s_addr; } else { for (i = 0; i < 6; i++) { dhcprMsgOut.ether->ether_dhost[i] = dhcpMsgIn.dhcp->chaddr[i]; dhcprMsgOut.ether->ether_shost[i] = ifp->haddr[i]; } if (msgtype == DHCPNAK) dhcprMsgOut.ip->ip_dst.s_addr = 0xffffffff; else dhcprMsgOut.ip->ip_dst.s_addr = dhcpMsgIn.dhcp->yiaddr.s_addr; dhcprMsgOut.ip->ip_src.s_addr = ifp->ipaddr.s_addr;#ifdef DHCPR_DEBUG inet_ntoa_b (dhcprMsgOut.ip->ip_src, srcAddr); inet_ntoa_b (dhcprMsgOut.ip->ip_dst, dstAddr); logMsg ("Sending reply from %s to %s.\n", srcAddr, dstAddr, 0, 0, 0, 0); logMsg ("Link layer source: %02x:%02x:%02x:%02x:%02x:%02x.\n", dhcprMsgOut.ether->ether_shost[0], dhcprMsgOut.ether->ether_shost[1], dhcprMsgOut.ether->ether_shost[2], dhcprMsgOut.ether->ether_shost[3], dhcprMsgOut.ether->ether_shost[4], dhcprMsgOut.ether->ether_shost[5]); logMsg ("Link layer destination: %02x:%02x:%02x:%02x:%02x:%02x.\n", dhcprMsgOut.ether->ether_dhost[0], dhcprMsgOut.ether->ether_dhost[1], dhcprMsgOut.ether->ether_dhost[2], dhcprMsgOut.ether->ether_dhost[3], dhcprMsgOut.ether->ether_dhost[4], dhcprMsgOut.ether->ether_dhost[5]);#endif } dhcprMsgOut.ether->ether_type = ETHERTYPE_IP; dhcprMsgOut.udp->uh_sport = dhcps_port; dhcprMsgOut.udp->uh_dport = dhcpc_port; dhcprMsgOut.udp->uh_ulen = htons (dhcplen + UDPHL); dhcprMsgOut.udp->uh_sum = get_udpsum (dhcprMsgOut.ip, dhcprMsgOut.udp); dhcprMsgOut.ip->ip_v = IPVERSION; dhcprMsgOut.ip->ip_hl = IPHL >> 2; dhcprMsgOut.ip->ip_tos = 0; dhcprMsgOut.ip->ip_len = htons (dhcplen + UDPHL + IPHL); dhcprMsgOut.ip->ip_id = dhcprMsgOut.udp->uh_sum; dhcprMsgOut.ip->ip_ttl = 0x20; /* XXX */ dhcprMsgOut.ip->ip_p = IPPROTO_UDP; total = dhcplen + IPHL + UDPHL; if (total <= ETHERMTU) { dhcprMsgOut.ip->ip_off = 0; dhcprMsgOut.ip->ip_sum = get_ipsum (dhcprMsgOut.ip);#ifdef DHCPR_DEBUG logMsg ("Writing %d bytes.\n", total, 0, 0, 0, 0, 0);#endif result = etherOutput (pIf, dhcprMsgOut.ether, (char *)dhcprMsgOut.ip, total);#ifdef DHCPR_DEBUG if (result != OK) logMsg ("Error %d relaying message to client.\n", errno, 0, 0, 0, 0, 0);#endif } else {#define MTU (ETHERMTU - IPHL) char *n, *end, *begin; char sendbuf [ETHERMTU]; struct iovec sbufvec[2]; sbufvec[0].iov_base = (char *)dhcprMsgOut.ether; sbufvec[0].iov_len = ETHERHL; begin = (char *) dhcprMsgOut.udp; end = &begin [total]; sbufvec[1].iov_base = sendbuf; for (n = begin; n < end; n += MTU) { if ((end - n) >= MTU) { sbufvec[1].iov_len = MTU; dhcprMsgOut.ip->ip_len = htons (ETHERMTU); dhcprMsgOut.ip->ip_off = htons(IP_MF | ((((n - begin) / 8)) & 0x1fff)); dhcprMsgOut.ip->ip_sum = get_ipsum(dhcprMsgOut.ip); bcopy ( (char *)dhcprMsgOut.ip, sendbuf, IPHL); bcopy ( (char *)n, &sendbuf [IPHL], MTU); } else { sbufvec[1].iov_len = end - n; dhcprMsgOut.ip->ip_len = htons (IPHL + end - n); dhcprMsgOut.ip->ip_off = htons(((n - begin) / 8) & 0x1fff); dhcprMsgOut.ip->ip_sum = get_ipsum(dhcprMsgOut.ip); bcopy ( (char *)dhcprMsgOut.ip, sendbuf, IPHL); bcopy ( (char *)n, &sendbuf [IPHL], end - n); } etherOutput (pIf, dhcprMsgOut.ether, sendbuf, dhcprMsgOut.ip->ip_len); } } return; }/********************************************************************************* read_server_db - read IP addresses to receive relayed packets** This routine extracts the IP address entries hard-coded into usrNetwork.c as * dhcpTargetTbl[] and stores them in a circular linked list. Each of these * address entries must be on a different subnet from the calling server* or relay agent. Each entry in the list will receive a copy of every DHCP or* BOOTP message arriving at the client port.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void read_server_db (int dbsize) { char targetIP [sizeof ("255.255.255.255")]; struct server *srvp = NULL; struct server *lastp = NULL; int loop; /* Read IP addresses of target servers or relay agents. */ for (loop = 0; loop < dbsize; loop++) { sprintf (targetIP, "%s", pDhcpRelayTargetTbl [loop].pAddress); srvp = (struct server *)calloc (1, sizeof (struct server)); if (srvp == NULL) {#ifdef DHCPR_DEBUG logMsg ("Memory allocation error reading relay target database.\n", 0, 0, 0, 0, 0, 0);#endif break; } srvp->ip.s_addr = inet_addr (targetIP); if (srvp->ip.s_addr == -1) {#ifdef DHCPR_DEBUG logMsg ("Conversion error reading relay target database.\n", 0, 0, 0, 0, 0, 0);#endif free (srvp); continue; } dhcpNumTargets++; srvp->next = pDhcpTargetList; if (pDhcpTargetList == NULL) lastp = srvp; pDhcpTargetList = srvp; } if (lastp == NULL) /* No target DHCP servers. */ return; /* Create circular list of DHCP server addresses. */ lastp->next = pDhcpTargetList; logMsg ("read %d entries from relay target database", dhcpNumTargets, 0, 0, 0, 0, 0); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -