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

📄 dhcps.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* dhcps.c - WIDE project DHCP server routines *//* Copyright 1984 - 2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01n,23apr02,wap  use dhcpTime() instead of time() (SPR #68900), also use                 BPF_WORDALIGN() when traversing multiple packets in BPF                 buffers (SPR #74215)01m,08mar02,wap  Return sane lease renewal times for clients that request                 leases without specifying their own lease times (SPR #73243)01l,31oct01,vvv  allow low-priority tasks to run while server waits for 		 ICMP reply (SPR #33132)01k,12oct01,rae  merge from truestack ver 01s, base 01h                 SPRs 70184, 69547, 34799, 6680801j,24oct00,spm  fixed modification history after tor3_x merge; fixed invalid                 socket reference (SPR #27246)01i,23oct00,niq  merged from version 01j of tor3_x branch (base version 01h)01h,01mar99,spm  corrected checksum calculation for ICMP requests (SPR #24745)01g,06oct97,spm  removed reference to deleted endDriver global; replaced with                 support for dynamic driver type detection; split interface                 name into device name and unit number01f,26aug97,spm  rearranged functions to consolidate lease selection routines01e,02jun97,spm  changed DHCP option tags to prevent name conflicts (SPR #8667)                 and updated man pages01d,06may97,spm  changed memory access to align IP header on four byte                  boundary and corrected format of lease record01c,28apr97,spm  allowed user to change DHCP_MAX_HOPS setting01b,18apr97,spm  added conditional include DHCPS_DEBUG for displayed output01a,07apr97,spm  created by modifying WIDE project DHCP implementation*//*DESCRIPTIONThis library implements the server side of the Dynamic Host ConfigurationProtocol (DHCP). DHCP is an extension of BOOTP. Like BOOTP, it allows atarget to configure itself dynamically by obtaining its IP address, aboot file name, and the DHCP server's address over the network. Additionally,DHCP provides for automatic reuse of network addresses by specifyingindividual leases as well as many additional options. The compatiblemessage format allows DHCP participants to interoperate with BOOTPparticipants.INCLUDE FILES: dhcpsLib.hSEE ALSO: RFC 1541, RFC 1533*//* includes */#include "dhcp/copyright_dhcp.h"#include "vxWorks.h"#include "net/bpf.h"#include "logLib.h"#include "vxLib.h" 	/* checksum() declaration */#include "inetLib.h"#include "sockLib.h"#include "ioLib.h"#include "wdLib.h"#include "taskLib.h"#include "sysLib.h"#include "muxLib.h"#include "netinet/ip.h"#include "netinet/in_systm.h"#include "netinet/ip_icmp.h" #include <time.h>#include <stdio.h>#include <stdlib.h>#include "dhcp/dhcp.h"#include "dhcp/common.h"#include "dhcp/hash.h"#include "dhcp/dhcps.h"#include "dhcpsLib.h"#include "dhcp/common_subr.h"/* defines */#define MEMORIZE 90 	/* Seconds of delay before re-using offered lease. */#define E_NOMORE -2 	/* Error code: no more space in options field. */#ifndef VIRTUAL_STACK/* globals */int nbind; 		/* Number of active or pending lease records. */struct msg dhcpsMsgIn;	/* Pointers to components of incoming message. */struct msg dhcpsMsgOut;	/* Pointers to outgoing message parts. */char *dhcpsSendBuf;     /* Transmit buffer for outgoing messages. */char *dhcpsOverflowBuf; /* Extra space (for larger messages) starts here. */IMPORT struct if_info *dhcpsIntfaceList; 	/* Interfaces to monitor. */struct iovec sbufvec[2]; 	/* Socket access to outgoing message.                                  * sbufvec[0] is standard message.                                  * sbufvec[1] contains message extensions if                                 * client accepts longer messages.                                  */IMPORT int dhcpsMaxSize; /* Size of transmit buffer. */IMPORT int dhcpsBufSize; /* Size of receive buffer. */IMPORT u_short dhcps_port;IMPORT u_short dhcpc_port;/* locals */LOCAL unsigned char dhcpCookie[] = RFC1048_MAGIC; /* DHCP message indicator. */LOCAL int rdhcplen;		/* Size of received DHCP message. */LOCAL int overload; 		/* Options in sname or file fields? */LOCAL int off_options; 		/* Index into options field. */LOCAL int off_extopt; 		/* Index into any options in sbufvec[1]. */LOCAL int maxoptlen;		/* Space available for options. */LOCAL int off_file; 		/* Index into any options within file field. */LOCAL int off_sname; 		/* Index into any options in sname field. */#else#include "netinet/vsLib.h"#include "netinet/vsDhcps.h"#endif /* VIRTUAL_STACK *//* forward declarations */LOCAL int icmp_check (int, struct in_addr *);IMPORT STATUS dhcpsSend (struct ifnet *, char *, int,                         struct sockaddr_in *, char *, int, BOOL);IMPORT void dhcpServerRelay (struct if_info *);IMPORT void dhcpClientRelay (struct if_info *, int, char *);IMPORT void delarp (struct in_addr *, int);/********************************************************************************* dhcpsStart - execute the DHCP server** This routine receives DHCP requests from clients and generates replies. If* configured to do so, it may also act as a relay agent and forward these * requests to other servers or transfer replies to clients. It is the entry * point for the DHCP server task and should only be called internally.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/int dhcpsStart    (#ifndef VIRTUAL_STACK    void#else    int stackNum#endif /* VIRTUAL_STACK */    )    {    struct if_info *ifp; 	/* pointer to receiving interface descriptor */    int n = 0; 			/* number of bytes received */    int msgtype; 		/* DHCP message type, or BOOTP indicator */    char *option = NULL; 	/* pointer to access message options */    struct bpf_hdr *    pMsgHdr;    char *              pMsgData;    int                 msglen;    int                 curlen;    int                 totlen;         /* Amount of data in BPF buffer. */#ifdef VIRTUAL_STACK    if (virtualStackNumTaskIdSet (stackNum) == ERROR)        return (ERROR);#endif /* VIRTUAL_STACK */    /* Main loop - read and process incoming messages. */    FOREVER         {         garbage_collect ();      /* remove expired leases from hash table. */        /* select and read from interfaces */        ifp = read_interfaces (dhcpsIntfaceList, &n, dhcpsBufSize);        if (ifp == NULL)            continue;        /* Divide each DHCP message in buffer into protocol sections. */        msglen = curlen = 0;        totlen = n;        pMsgHdr = (struct bpf_hdr *)ifp->buf;        pMsgData = ifp->buf;        while (curlen < totlen)            {            msglen = BPF_WORDALIGN(pMsgHdr->bh_hdrlen + pMsgHdr->bh_caplen);            curlen += msglen;            /* Set the IP pointer to skip the BPF and link level headers. */            dhcpsMsgIn.ip = (struct ip *) (pMsgData + pMsgHdr->bh_hdrlen +                                           pMsgHdr->bh_linklen);            if ( (dhcpsMsgIn.ip->ip_dst.s_addr == 0xffffffff ||                   dhcpsMsgIn.ip->ip_dst.s_addr == ifp->ipaddr.s_addr) &&                  check_ipsum (dhcpsMsgIn.ip))                dhcpsMsgIn.udp =                (struct udphdr *)( (UCHAR *)dhcpsMsgIn.ip +                                              dhcpsMsgIn.ip->ip_hl * WORD);            else                {                /* Invalid IP header: ignore. */                pMsgData = pMsgData + msglen;                pMsgHdr = (struct bpf_hdr *)pMsgData;                continue;                }            if (check_udpsum (dhcpsMsgIn.ip, dhcpsMsgIn.udp))                dhcpsMsgIn.dhcp =                (struct dhcp *)( (UCHAR *)dhcpsMsgIn.udp + UDPHL);            else                {                /* Invalid UDP header: ignore. */                pMsgData = pMsgData + msglen;                pMsgHdr = (struct bpf_hdr *)pMsgData;                continue;                }            /*             * Perform function of relay agent for received server replies.             * (Changes contents of input message IP and UDP headers while             * sending to client).             */            dhcpMsgIn.ip = dhcpsMsgIn.ip;            dhcpMsgIn.udp = dhcpsMsgIn.udp;            dhcpMsgIn.dhcp = dhcpsMsgIn.dhcp;            if (dhcpMsgIn.dhcp->op == BOOTREPLY)                dhcpClientRelay (dhcpsIntfaceList, DHCPLEN (dhcpsMsgIn.udp),                                 dhcpsSendBuf);            if (dhcpsMsgIn.dhcp->op != BOOTREQUEST)                {                pMsgData = pMsgData + msglen;                pMsgHdr = (struct bpf_hdr *)pMsgData;                continue;                }            /* Process DHCP client message received at server port. */            rdhcplen = DHCPLEN (dhcpsMsgIn.udp);            msgtype = BOOTP;            option = pickup_opt (dhcpsMsgIn.dhcp, rdhcplen, _DHCP_MSGTYPE_TAG);            if (option != NULL)                msgtype = (int) *OPTBODY(option);#ifdef DHCPS_DEBUG            if (msgtype < BOOTP || msgtype > DHCPRELEASE)                logMsg ("dhcps: unknown message received.\n",                         0, 0, 0, 0, 0, 0);#endif            if (msgtype >= BOOTP && msgtype <= DHCPRELEASE)                if ( (process_msg [msgtype]) != NULL)                    (*process_msg [msgtype]) (ifp);            /*             * Relay received client messages if target addresses available.             * (Changes contents of input DHCP message when sending to             * server or relay agent - must process first).             */            dhcpMsgIn.udp = dhcpsMsgIn.udp;            dhcpMsgIn.dhcp = dhcpsMsgIn.dhcp;            if (pDhcpTargetList != NULL)                dhcpServerRelay (ifp);            pMsgData = pMsgData + msglen;            pMsgHdr = (struct bpf_hdr *)pMsgData;            }        }    }/********************************************************************************* haddrtos - convert hardware address to cache format** This routine converts the given hardware address to the <type>:<value> pair* used when adding lease record entries to permanent storage.** RETURNS: Pointer to converted string** ERRNO: N/A** NOMANUAL*/char * haddrtos    (    struct chaddr *haddr 	/* pointer to parsed hardware address */    )    {    int i;    int fin;    char tmp[3];    static char result [MAX_HLEN * 2 + 8];     /* it seems enough */    bzero (result, sizeof (result));    fin = haddr->hlen;    if (fin > MAX_HLEN)        fin = MAX_HLEN;    sprintf (result, "%d:0x", haddr->htype);    for (i = 0; i < fin; i++)         {        sprintf(tmp, "%.2x", haddr->haddr[i] & 0xff);        strcat(result, tmp);        }    return (result);    }/********************************************************************************* cidtos - convert client identifier to cache format** This routine converts the given client identifier to the <type>:<value> pair* used when adding lease record entries to permanent storage. It also* adds the current subnet number so that the server can deny inaccurate * leases caused by a client changing subnets. When used for user output, the* subnet is not included in the converted string.** RETURNS: Pointer to converted string** ERRNO: N/A** NOMANUAL*/char * cidtos    (    struct client_id *cid,	/* pointer to parsed client ID */    int withsubnet 		/* flag for adding subnet to output string */    )    {    int i = 0;    static char result [MAXOPT * 2 + sizeof ("255.255.255.255") + 3];    char tmp [sizeof ("255.255.255.255") + 1];    sprintf (result, "%d:0x", cid->idtype);    for (i = 0; i < cid->idlen; i++)         {        sprintf (tmp, "%.2x", cid->id[i] & 0xff);        strcat (result, tmp);        }    if (withsubnet)         {        inet_ntoa_b (cid->subnet, tmp);        strcat (result, ":");        strcat (result, tmp);        }    return (result);    }/********************************************************************************* get_reqlease - Retrieve requested lease value ** This routine extracts the desired lease duration from the options field of * the DHCP client request and converts it to host byte order.** RETURNS: Requested lease duration, or 0 if none.** ERRNO: N/A** NOMANUAL*/  static u_long get_reqlease    (    struct dhcp *msg, 		/* pointer to incoming message */    int length 			/* length of incoming message */    )    {    char *option = NULL;    u_long retval = 0;    if ( (option = pickup_opt (msg, length, _DHCP_LEASE_TIME_TAG)) != NULL)         retval = GETHL (OPTBODY (option));    return (retval);    }/********************************************************************************* get_cid - Retrieve client identifier** This routine extracts the client identifier from the options field of the* DHCP client request and stores the <type>:<value> pair in the given * structure. If no explicit client ID is given, the routine uses the hardware* address, as specified by RFC 1541.** RETURNS: N/A*

⌨️ 快捷键说明

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