⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcprlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
字号:
/* dhcprLib.c - DHCP relay agent library *//* Copyright 1984 - 1997 Wind River Systems, Inc.  */#include "copyright_wrs.h"/*modification history____________________01j,04dec97,spm  added code review modifications01i,06oct97,spm  split interface name into device name and unit number; removed                 reference to deleted endDriver global; added stub routine to                 support delayed startup01h,25sep97,gnn  SENS beta feedback fixes01g,02sep97,spm  removed excess debug message (SPR #9149); corrected removal                 of target list in cleanup routine01f,26aug97,spm  reorganized code and added support for UDP port selection01e,12aug97,gnn  changes necessitated by MUX/END update.01d,02jun97,spm  updated man pages and added ERRNO entries01c,06may97,spm  changed memory access to align IP header on four byte boundary01b,10apr97,kbw  changed title line to match actual file name 01a,07apr97,spm  created by modifying WIDE project DHCP implementation*//*DESCRIPTIONThis library implements a relay agent for the Dynamic Host ConfigurationProtocol (DHCP).  DHCP is an extension of BOOTP.  Like BOOTP, it allows a target to configure itself dynamically by using the network to get its IP address, a boot file name, and the DHCP server's address.  The relay agent forwards DHCP messages between clients and servers resident on different subnets.  The standard DHCP server, if present on a subnet, can also forward messages across subnet boundaries.  The relay agent is needed only if there is no DHCP server running on the subnet.  The dhcprLibInit()routine links this library into the VxWorks system.  This happens automaticallyif INCLUDE_DHCPR is defined at the time the system is built, as long as INCLUDE_DHCPS is <not> also defined.HIGH-LEVEL INTERFACEThe dhcprInit() routine initializes the relay agent automatically.  The relay agent forwards incoming DHCP messages to the IP addresses specified at build time in the 'dhcpTargetTbl[]' array in usrNetwork.c. INTERNALThe core relay agent code, derived from code developed by the WIDE project,is located in the dhcpr.c module in the directory /vobs/wpwr/target/src/dhcp.INCLUDE FILES: dhcprLib.hSEE ALSO: RFC 1541, RFC 1533*//* includes */#include "dhcp/copyright_dhcp.h"#include "vxWorks.h"#include <stdio.h>#include <stdlib.h>#include <netinet/if_ether.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/udp.h>#include <sys/ioctl.h>#include <vxLib.h>             /* checksum() declaration. */#include "end.h"#include "ipProto.h"#include "logLib.h"#include "rngLib.h"#include "semLib.h"#include "sockLib.h"#include "dhcprLib.h"#include "dhcp/dhcp.h"#include "dhcp/common.h"#include "dhcp/common_subr.h"/* globals */IMPORT int 	dhcpSPort; 	/* Port used by DHCP servers */IMPORT int 	dhcpCPort; 	/* Port used by DHCP clients */IMPORT RING_ID dhcpEventRing; 	/* Identifies arriving DHCP messages. */IMPORT RING_ID dhcpMsgRing; 	/* Contents of arriving messages. */IMPORT SEM_ID  dhcpEventSem; 	/* Signals arrival of DHCP messages. */IMPORT struct iovec sbufvec[2];            /* send buffer */IMPORT struct msg dhcprMsgOut;void dhcprCleanup (int checkpoint);/* locals */struct if_info *dhcprIntfaceList = NULL;/********************************************************************************* dhcprLibInit - empty stub routine for linker** This routine links the DHCP relay agent code into the runtime image.  It * includes the relay agent code even if the initialization routines are * deferred and executed by an application once the target addresses are known.* * RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void dhcprLibInit (void)    {    return;    }/********************************************************************************* dhcprInit - set up the DHCP relay agent parameters and data structures** This routine creates the necessary data structures to monitor the specified* network interfaces for incoming DHCP messages and forward the messages to* the given Internet addresses.* * RETURNS: OK, or ERROR if could not initialize.** ERRNO: N/A** NOMANUAL*/STATUS dhcprInit    (    struct ifnet **	ppIf, 		/* network devices used by server */    int			numDev, 	/* number of devices */    DHCP_TARGET_DESC *  pTargetTbl, 	/* table of receiving DHCP servers */    int                 targetSize 	/* size of DHCP server table */    )    {    struct if_info *pIf = NULL;          /* pointer to interface */    int loop;    if (ppIf == NULL)        return (ERROR);    if (numDev == 0)        return (ERROR);    for (loop = 0; loop < numDev; loop++)        {        pIf = (struct if_info *)calloc (1, sizeof (struct if_info));        if (pIf == NULL)             {            logMsg ("Memory allocation error.\n", 0, 0, 0, 0, 0, 0);            dhcprCleanup (1);            return (ERROR);            }        pIf->buf = (char *)memalign (4, DHCP_MSG_SIZE + DHCPS_OFF);        if (pIf->buf == NULL)            {            logMsg ("Memory allocation error.\n", 0, 0, 0, 0, 0, 0);            dhcprCleanup (1);            return (ERROR);            }        bzero (pIf->buf, DHCP_MSG_SIZE + DHCPS_OFF);        pIf->next = dhcprIntfaceList;        dhcprIntfaceList = pIf;        /* Fill in device name and hardware address. */        sprintf (pIf->name, "%s", ppIf[loop]->if_name);        pIf->unit = ppIf[loop]->if_unit;        pIf->htype = ETHER;        pIf->hlen = _ETHERADDRLEN;        bcopy ( (char *) ( (struct arpcom *)ppIf[loop])->ac_enaddr,               (char *)&pIf->haddr, pIf->hlen);        }    /* Access target DHCP server data. */    pDhcpRelayTargetTbl = pTargetTbl;  /* read database of DHCP servers */    if (targetSize != 0)        read_server_db (targetSize);     /* Always use default ports for client and server. */    dhcps_port = htons (dhcpSPort);    dhcpc_port = htons (dhcpCPort);    /* Fill in subnet mask and IP address for each monitored interface. */    pIf = dhcprIntfaceList;    while (pIf != NULL)        {         if (open_if (pIf) < 0)             {            dhcprCleanup (2);            return (ERROR);            }        pIf = pIf->next;        }    dhcpEventRing = rngCreate (EVENT_RING_SIZE);    if (dhcpEventRing == NULL)        {        logMsg ("Error: Couldn't allocate memory.\n", 0, 0, 0, 0, 0, 0);        dhcprCleanup (2);        return (ERROR);        }    dhcpMsgRing = rngCreate (MESSAGE_RING_SIZE);    if (dhcpMsgRing == NULL)        {        logMsg ("Error: Couldn't allocate memory.\n", 0, 0, 0, 0, 0, 0);        dhcprCleanup (3);        return (ERROR);        }    dhcpEventSem = semCCreate (SEM_Q_FIFO, 0);     if (dhcpEventSem == NULL)        {        logMsg("Error: Couldn't allocate memory.\n", 0, 0, 0, 0, 0, 0);        dhcprCleanup (4);        return (ERROR);        }    return (OK);    }/********************************************************************************* dhcprCleanup - remove data structures** This routine frees all dynamically allocated memory obtained by the DHCP* relay agent.  It is called at multiple points before the program exits due to* an error occurring or manual shutdown.  The checkpoint parameter indicates * which data structures have been created.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void dhcprCleanup     (    int checkpoint 	/* Progress identifier indicating created resources */    )    {    int current = 0;    struct if_info *pIf;    DHCP_SERVER_DESC * 	pServer;    int loop;    /* Checkpoint 0 is empty. */    current++;    if (current > checkpoint)        return;    while (dhcprIntfaceList != NULL)         /* Checkpoint 1 */        {        pIf = dhcprIntfaceList;        if (pIf->buf != NULL)            free (pIf->buf);        dhcprIntfaceList = dhcprIntfaceList->next;        free (pIf);        }    current++;    if (current > checkpoint)        return;    /* Remove elements of circular list created by read_server_db(). */                                             /* Checkpoint 2 */    for (loop = 0; loop < dhcpNumTargets; loop++)        {        pServer = pDhcpTargetList;        pDhcpTargetList = pDhcpTargetList->next;        free (pServer);        }    current++;    if (current > checkpoint)        return;    rngDelete (dhcpEventRing);               /* Checkpoint 3 */    current++;    if (current > checkpoint)        return;    rngDelete (dhcpMsgRing);                 /* Checkpoint 4 */    current++;    if (current > checkpoint)        return;    semDelete (dhcpEventSem);                /* Checkpoint 5 */    current++;    if (current > checkpoint)        return;    return;    }/********************************************************************************* dhcprInputHook - packet filter for DHCP client or relayed messages** This routine filters all DHCP messages received at the server port from * incoming ethernet traffic.  It is called by the network interface driver * when a new input frame comes in from the network.* * RETURNS: TRUE if the ethernet frame is handle by this routine.  No further* processing by the network driver is needed.* FALSE if the frame is not a DHCP client message. The ethernet frame* is then handled by the network driver.** ERRNO: N/A** NOMANUAL*/BOOL dhcprInputHook    (    struct ifnet *      pIf, 	/* interface where packet was received */    FAST char * 	einput, 	/* contents of received packet */    FAST int 		length 		/* length of received packet */    )    {    int offset;    struct if_info *ifp;    int retval;                    /* Return values */    FAST struct ether_header*   eh; /* pointer to ethernet header */    FAST struct ip*            iph; /* pointer to IP header */    FAST struct udphdr*       udph; /* pointer to UDP header */    EVENT_DATA 	newEvent;    /* Find offset of receiving interface. */    offset = 0;    ifp = dhcprIntfaceList;    while (ifp != NULL)        {        if ( (strcmp (pIf->if_name, ifp->name) == 0) &&             (pIf->if_unit == ifp->unit))            break;        offset++;        ifp = ifp->next;        }    if (ifp == NULL)            /* Unrecognized interface - ignore. */        return (FALSE);    eh = (struct ether_header *) einput;    iph = (struct ip *) &einput [SIZEOF_ETHERHEADER];#if BSD<44    udph = (struct udphdr *) &einput [SIZEOF_ETHERHEADER +                                      (iph->ip_v_hl & 0xf) * 4];#else    udph = (struct udphdr *) &einput [SIZEOF_ETHERHEADER +                                      iph->ip_hl * 4];#endif    if (length <= SIZEOF_ETHERHEADER)        return (FALSE);    if (ntohs (eh->ether_type) != ETHERTYPE_IP)        return (FALSE);    if (iph->ip_p != IPPROTO_UDP)        return (FALSE);    if (udph->uh_dport != dhcps_port)        return (FALSE);    /* Message recognized - store and signal processing thread. */    /* Adjust message size (ignores trailers added by some drivers). */   if (length > DHCP_MSG_SIZE)       length = DHCP_MSG_SIZE;    newEvent.source = offset;    newEvent.length = length;    retval = rngBufPut (dhcpEventRing, (char *)&newEvent, sizeof (newEvent));    if (retval == sizeof (newEvent))        {        /* Ignore storage error - notifications with no message are OK. */        retval = rngBufPut (dhcpMsgRing, einput, length);        if (retval != length)            logMsg ("Warning: DHCP message not stored.\n", 0, 0, 0, 0, 0, 0);        semGive (dhcpEventSem);        }    return (TRUE);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -