📄 dhcprelay.c
字号:
/* dhcpRelay.c - DHCP server and relay agent shared code library *//* Copyright 1984 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01e,07may02,wap Put debug messages under DHCPR_DEBUG (SPR #76495)01d,27mar02,wap call ip_mloopback() rather than calling looutput() directly (SPR #72246)01c,22mar02,wap avoid division by zero in dhcpServerRelay() (SPR #74456)01b,06dec01,wap Add NPT support01a,12oct01,rae merge from truestack ver 01n, base 01f (SPR #69547)01i,17nov00,spm added support for BSD Ethernet devices01h,24oct00,spm fixed merge from tor3_x branch and updated mod history01g,23oct00,niq merged from version 01h of tor3_x branch (base version 01f)01f,04dec97,spm added code review modifications01e,06oct97,spm split interface name into device name and unit number; fixed errors in debugging output01d,02jun97,spm changed DHCP option tags to prevent name conflicts (SPR #8667) and updated man pages01c,28apr97,spm limited maximum number of hops to 16 for RFC compliance01b,18apr97,spm added conditional include DHCPR_DEBUG for displayed output01a,07apr97,spm created by modifying WIDE project DHCP implementation*//*DESCRIPTIONThis library contains the code used by the DHCP relay agent to transfer packets between DHCP or BOOTP clients and DHCP servers. The DHCP serverwill also use this code if configured to act as a relay agent. Thelibrary also includes the shared transmit routine which sends unicastpackets to a DHCP client without performing address resolution, sincethe destination IP address is not yet resolvable.INCLUDE_FILES: dhcprLib.h*//* * WIDE Project DHCP Implementation * Copyright (c) 1995 Akihiro Tominaga * Copyright (c) 1995 WIDE Project * All rights reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided only with the following * conditions are satisfied: * * 1. Both the copyright notice and this permission notice appear in * all copies of the software, derivative works or modified versions, * and any portions thereof, and that both notices appear in * supporting documentation. * 2. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by WIDE Project and * its contributors. * 3. Neither the name of WIDE Project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED. * * Feedback of the results generated from any improvements or * extensions made to this software would be much appreciated. * Any such feedback should be sent to: * * Akihiro Tominaga * WIDE Project * Keio University, Endo 5322, Kanagawa, Japan * (E-mail: dhcp-dist@wide.ad.jp) * * WIDE project has the rights to redistribute these changes. *//* includes */#include "vxWorks.h"#include "vxLib.h" /* checksum() declaration. */#include <stdio.h>#include <stdlib.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <arpa/inet.h>#include "logLib.h"#include "sockLib.h"#include "ioLib.h"#include "ipProto.h" /* IP_DRV_CTRL definition. */#include "muxLib.h"#include "tickLib.h" /* tickGet() declaration. */#ifdef DHCPR_DEBUG#include "inetLib.h"#endif#include "dhcprLib.h"#include "dhcp/dhcp.h"#include "dhcp/common.h"#include "dhcp/common_subr.h"/* globals */#ifndef VIRTUAL_STACKDHCP_TARGET_DESC *pDhcpRelayTargetTbl;struct server *pDhcpTargetList = NULL;int dhcpNumTargets = 0;struct msg dhcpMsgIn;struct msg dhcprMsgOut;u_short dhcps_port;u_short dhcpc_port;#else#include "netinet/vsLib.h"#include "netinet/vsDhcps.h"#endif /* VIRTUAL_STACK *//* forward declarations */IMPORT void ip_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in *, struct rtentry *rt);void dhcpServerRelay (struct if_info *);void dhcpClientRelay (struct if_info *, int, char *);LOCAL STATUS forwarding();/********************************************************************************* dhcpsSend - transmit an outgoing DHCP message** This routine uses the MUX interface to send an IP packet containing a* DHCP message independently of the link level type. It is derived from* the ipOutput() routine in the ipProto.c module, but uses the available* hardware address of the original sender as the destination link-level* address instead of performing address resolution.** Bypassing the normal address resolution process is required since the* destination IP address has not yet been assigned so (for instance)* ARP requests would fail, preventing delivery of the reply.** RETURNS: OK, or ERROR if send fails.** ERRNO: N/A** NOMANUAL*/STATUS dhcpsSend ( struct ifnet * pIf, /* interface for sending message */ char * pHwAddr, /* destination link-level address */ int hlen, /* size of link-level address, in bytes */ struct sockaddr_in * pDest, /* destination IP address for message */ char * pData, /* IP packet containing DHCP message */ int size, /* amount of data to send */ BOOL broadcastFlag /* broadcast packet? */ ) { IP_DRV_CTRL * pDrvCtrl; /* Protocol-specific information. */ void * pIpCookie; /* Result of muxBind() routine for device */ struct mbuf * pMbuf; u_short etype; int s; if ((pIf->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) return (ERROR); /* ENETDOWN */ pDrvCtrl = (IP_DRV_CTRL *)pIf->pCookie; if (pDrvCtrl == NULL) /* Undefined error in original transmit code. */ return (ERROR); pIpCookie = pDrvCtrl->pIpCookie; if (pIpCookie == NULL) return (ERROR); /* EINVAL */ pMbuf = bcopy_to_mbufs (pData, size, 0, pIf, NONE); if (pMbuf == NULL) return (ERROR); /* ENOBUFS */ s = splnet (); pIf->if_lastchange = tickGet (); /* Setup existing mBlk structures and build link-level header. */ etype = htons (ETHERTYPE_IP); pDrvCtrl->pSrc->m_data = (char *)&((struct arpcom *)pIf)->ac_enaddr; bcopy (pHwAddr, (char *)pDrvCtrl->pDstAddr, hlen); pDrvCtrl->pDst->mBlkHdr.reserved = etype; pDrvCtrl->pSrc->mBlkHdr.reserved = etype; if (broadcastFlag) { /* * Use the registered resolve routine to get the link-level broadcast. */ pMbuf->mBlkHdr.mFlags |= M_BCAST; /* Loopback a copy of the data if using a simplex interface. */ if (pIf->if_flags & IFF_SIMPLEX) { ip_mloopback (pIf, pMbuf, (struct sockaddr_in *)pDest, NULL); } } if (pDrvCtrl->nptFlag) { if (pIf->if_addrlen) { M_PREPEND(pMbuf, pIf->if_addrlen, M_DONTWAIT); if (pMbuf == NULL) { netMblkClChainFree (pMbuf); return(ERROR); } ((M_BLK_ID)pMbuf)->mBlkPktHdr.rcvif = 0; /* Store the destination address. */ bcopy (pDrvCtrl->pDstAddr, pMbuf->m_data, pIf->if_addrlen); } /* Save the network protocol type. */ ((M_BLK_ID)pMbuf)->mBlkHdr.reserved = etype; } else { pMbuf = muxLinkHeaderCreate (pDrvCtrl->pIpCookie, pMbuf, pDrvCtrl->pSrc, pDrvCtrl->pDst, broadcastFlag); if (pMbuf == NULL) { netMblkClChainFree (pMbuf); return (ERROR); /* ENOBUFS */ } } /* * Queue message on interface, and start output if interface * not yet active. */ if (IF_QFULL(&pIf->if_snd)) { IF_DROP(&pIf->if_snd); splx(s); netMblkClChainFree (pMbuf); return (ERROR); /* ENOBUFS */ } IF_ENQUEUE(&pIf->if_snd, pMbuf); pIf->if_start (pIf); pIf->if_obytes += pMbuf->mBlkHdr.mLen; if (pMbuf->m_flags & M_MCAST || pMbuf->m_flags & M_BCAST) pIf->if_omcasts++; splx(s); return (OK); }/********************************************************************************* dhcpServerRelay - send incoming DHCP/BOOTP message to client port** This routine relays a DHCP or BOOTP message to the client port of * every DHCP server or relay agent whose IP address is contained in the * circular linked list of targets. That list is constructed during startup of * the relay agent (or server, if configured to relay messages). The routine* accesses global pointers already set to indicate the outgoing message. * All messages are discarded after the hops field exceeds 16 to comply with* the relay agent behavior specified in RFC 1542. The relay agent normally* discards such messages before this routine is called. They will only* be received by this routine if the user ignores the instructions in the* manual and sets the value of DHCP_MAX_HOPS higher than 16.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void dhcpServerRelay ( struct if_info *ifp ) { unsigned int hash; int i; struct server *srvp; dhcpMsgIn.dhcp->hops++; if (dhcpMsgIn.dhcp->hops >= 17) /* RFC limits to 16 hops - ignore. */ return; /* * If the target table is empty, bail, otherwise * trying to do the hash computation below will yield a * division by zero. */ if (dhcpNumTargets == 0) return; if (dhcpMsgIn.dhcp->giaddr.s_addr == 0) dhcpMsgIn.dhcp->giaddr.s_addr = ifp->ipaddr.s_addr; /* Quick and dirty load balancing - pick starting point in circular list. */ hash = (unsigned)checksum( (u_short *)dhcpMsgIn.dhcp->chaddr, (MAX_HLEN / 2)); hash %= dhcpNumTargets; srvp = pDhcpTargetList; for (i = 0; i < hash; i++) srvp = srvp->next; forwarding (srvp); return; }/********************************************************************************* forwarding - send DHCP/BOOTP message to target address** This routine relays a DHCP or BOOTP message to the specified target address.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static STATUS forwarding (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -