📄 dhcpslib.c
字号:
INTERNALThis library provides a wrapper for the WIDE project DHCP code found in thedirectory .../target/src/dhcp, which contains all the messageprocessing functions. This module uses the Berkeley Packet Filter servicesto intercept incoming DHCP messages and signals their arrival to the WIDEproject code using a shared semaphore.INCLUDE FILES: dhcpsLib.hSEE ALSO: RFC 1541, RFC 1533*//* includes */#include "vxWorks.h"#include "dhcp/copyright_dhcp.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 "inetLib.h"#include "end.h"#include "ipProto.h"#include "ioLib.h" /* close() declaration. */#include "logLib.h"#include "rngLib.h"#include "semLib.h"#include "sockLib.h"#include "taskLib.h"#include "muxLib.h"#include "dhcp/dhcp.h"#include "dhcp/common.h"#include "dhcp/hash.h"#include "dhcp/common_subr.h"#include "dhcpsLib.h"#include "bpfDrv.h"/* defines */#define _DHCPS_MAX_DEVNAME 26 /* "/bpf/dhcps" + max unit number + vs num *//* globals for both the regular and virtual stacks */#ifndef VIRTUAL_STACK/* globals */DHCPS_RELAY_DESC * pDhcpsRelaySourceTbl;DHCPS_LEASE_DESC * pDhcpsLeasePool;long dhcps_dflt_lease; /* Default for default lease length */long dhcps_max_lease; /* Default maximum lease length */SEM_ID dhcpsMutexSem; /* Synchronization for lease entry adds. */FUNCPTR dhcpsLeaseHookRtn = NULL; /* Accesses storage for lease bindings. */FUNCPTR dhcpsAddressHookRtn = NULL; /* Preserves additional address entries. */int dhcpsMaxSize; /* Transmit buffer size & largest supported message. */int dhcpsBufSize; /* Size of buffer for BPF devices */IMPORT struct iovec sbufvec[2]; /* send buffer */IMPORT struct msg dhcpsMsgOut;IMPORT struct hash_member *reslist;IMPORT struct hash_member *bindlist;IMPORT struct hash_tbl nmhashtable;IMPORT struct hash_tbl iphashtable;IMPORT struct hash_tbl cidhashtable;IMPORT struct hash_tbl relayhashtable;IMPORT struct hash_tbl paramhashtable;IMPORT char *dhcpsSendBuf;IMPORT char *dhcpsOverflowBuf;IMPORT u_short dhcps_port;IMPORT u_short dhcpc_port;/* locals */struct if_info *dhcpsIntfaceList = NULL;LOCAL BOOL dhcpsInitialized = FALSE;/* Berkeley Packet Filter instructions for catching DHCP messages. */LOCAL struct bpf_insn dhcpfilter[] = DHCPS_FILTER_DEFINE;LOCAL struct bpf_program dhcpread = { sizeof (dhcpfilter) / sizeof (struct bpf_insn), dhcpfilter };#else#include "netinet/vsLib.h"#include "netinet/vsDhcps.h"#endif /* VIRTUAL_STACK *//* forward declarations */LOCAL STATUS alloc_sbuf (int);void dhcpsCleanup (int);void dhcpsFreeResource (struct dhcp_resource *);IMPORT int resnmcmp();IMPORT int resipcmp();IMPORT int eval_symbol (void *, void *);IMPORT int open_if();IMPORT STATUS read_addrpool_file (void);IMPORT void read_server_db (int);IMPORT int process_entry (struct dhcp_resource *, DHCPS_ENTRY_DESC *);IMPORT void set_default (struct dhcp_resource *);/********************************************************************************* dhcpsInit - set up the DHCP server parameters and data structures** This routine creates the necessary data structures, builds the* server address pool, retrieves any lease or address information from * permanent storage through the user-provided hooks, and initializes the * network interfaces for monitoring. It is called at system startup if * INCLUDE_DHCPS is defined at the time the VxWorks image is built.** The <maxSize> parameter specifies the maximum length supported for any* DHCP message, including the UDP and IP headers and the largest link* level header for all supported devices. The smallest valid value is* 576 bytes, corresponding to the minimum IP datagram a host must accept.* Larger values will allow the server to handle longer DHCP messages.* * RETURNS: OK, or ERROR if could not initialize.**/STATUS dhcpsInit ( DHCPS_CFG_PARAMS *pDhcpsCfg /* configuration parameters */ ) { struct if_info *pIf = NULL; /* pointer to interface */ struct ifnet *pCIf = NULL; /* pointer to current interface */ char bpfDevName [_DHCPS_MAX_DEVNAME]; /* "/bpf/dhcps" + max unit number */#ifdef VIRTUAL_STACK char temp [_DHCPS_MAX_DEVNAME];#endif /* VIRTUAL_STACK */ int bpfDev; struct ifreq ifreq; struct sockaddr_in send_addr; int loop; int result; STATUS status; if (pDhcpsCfg == (DHCPS_CFG_PARAMS *)NULL) return (ERROR);#ifdef VIRTUAL_STACK if (dhcpsVsInit () == ERROR) return (ERROR);#endif /* VIRTUAL_STACK */ /* It must return error, if it is already initialized */ if (dhcpsInitialized) return (ERROR); if (pDhcpsCfg->dhcpMaxMsgSize < DFLTDHCPLEN + UDPHL + IPHL) return (ERROR); if (bpfDrv () == ERROR) return (ERROR); dhcpsMaxSize = pDhcpsCfg->dhcpMaxMsgSize; dhcpsBufSize = pDhcpsCfg->dhcpMaxMsgSize + sizeof (struct bpf_hdr); dhcps_dflt_lease = pDhcpsCfg->dhcpsDfltLease; dhcps_max_lease = pDhcpsCfg->dhcpsMaxLease; dhcpsLeaseHookAdd (pDhcpsCfg->pDhcpsLeaseFunc); dhcpsAddressHookAdd (pDhcpsCfg->pDhcpsAddrFunc);#ifdef VIRTUAL_STACK sprintf(temp, "/bpf/vs%d_dhcps", myStackNum ); if (bpfDevCreate (temp, pDhcpsCfg->numDev, dhcpsBufSize) == ERROR)#else if (bpfDevCreate ("/bpf/dhcps", pDhcpsCfg->numDev, dhcpsBufSize) == ERROR)#endif /* VIRTUAL_STACK */ return (ERROR); dhcpsMutexSem = semBCreate (SEM_Q_FIFO, SEM_FULL); if (dhcpsMutexSem == NULL) return (ERROR); bzero ( (char *)&ifreq, sizeof (ifreq)); srand (taskIdSelf ()); /* Validate the MTU size. */ for (loop = 0; loop < pDhcpsCfg->numDev; loop++) { pCIf = ifunit (pDhcpsCfg->pDhcpsIfTbl[loop].ifName); if (pCIf == NULL) return (ERROR); if (pCIf->if_mtu == 0) /* No MTU size given: not attached? */ return (ERROR); if (pCIf->if_mtu < DHCP_MSG_SIZE) return (ERROR); } /* * Alter the filter program to check for the correct length values and * use the specified UDP destination port and maximum hop count. */ /* IP length must at least equal a DHCP message with 4 option bytes. */ dhcpfilter [6].k = (DFLTDHCPLEN - DFLTOPTLEN + 4) + UDPHL + IPHL; dhcpfilter [14].k = pDhcpsCfg->dhcpSPort; /* Use actual destination port in test. */ /* UDP length must at least equal a DHCP message with 4 option bytes. */ dhcpfilter [16].k = (DFLTDHCPLEN - DFLTOPTLEN + 4) + UDPHL; dhcpfilter [18].k = pDhcpsCfg->dhcpMaxHops; /* Use real maximum hop count. */ /* Store the interface control information and get each BPF device. */ for (loop = 0; loop < pDhcpsCfg->numDev; loop++) { pCIf = ifunit (pDhcpsCfg->pDhcpsIfTbl[loop].ifName); pIf = (struct if_info *)calloc (1, sizeof (struct if_info)); if (pIf == NULL) { logMsg ("Memory allocation error.\n", 0, 0, 0, 0, 0, 0); dhcpsCleanup (1); return (ERROR); } pIf->buf = (char *)memalign (4, dhcpsBufSize); if (pIf->buf == NULL) { logMsg ("Memory allocation error.\n", 0, 0, 0, 0, 0, 0); dhcpsCleanup (1); return (ERROR); } bzero (pIf->buf, dhcpsBufSize);#ifdef VIRTUAL_STACK sprintf (bpfDevName, "/bpf/vs%d_dhcps%d", myStackNum, loop);#else sprintf (bpfDevName, "/bpf/dhcps%d", loop);#endif /* VIRTUAL_STACK */ bpfDev = open (bpfDevName, 0, 0); if (bpfDev < 0) { logMsg ("BPF device creation error.\n", 0, 0, 0, 0, 0, 0); dhcpsCleanup (1); return (ERROR); } /* Enable immediate mode for reading messages. */ result = 1; result = ioctl (bpfDev, BIOCIMMEDIATE, (int)&result); if (result != 0) { logMsg ("BPF device creation error.\n", 0, 0, 0, 0, 0, 0); dhcpsCleanup (1); return (ERROR); } result = ioctl (bpfDev, BIOCSETF, (int)&dhcpread); if (result != 0) { logMsg ("BPF filter assignment error.\n", 0, 0, 0, 0, 0, 0); dhcpsCleanup (1); return (ERROR); } sprintf (ifreq.ifr_name, "%s", pDhcpsCfg->pDhcpsIfTbl[loop].ifName ); result = ioctl (bpfDev, BIOCSETIF, (int)&ifreq); if (result != 0) { logMsg ("BPF interface attachment error.\n", 0, 0, 0, 0, 0, 0); dhcpsCleanup (1); return (ERROR); } pIf->next = dhcpsIntfaceList; dhcpsIntfaceList = pIf; /* * Fill in device name and hardware address using the information * set when the driver attached to the IP network protocol. */ sprintf (pIf->name, "%s", pCIf->if_name); pIf->unit = pCIf->if_unit; pIf->bpfDev = bpfDev; if (muxDevExists (pCIf->if_name, pCIf->if_unit) == FALSE) pIf->htype = ETHER; else pIf->htype = dhcpConvert (pCIf->if_type); pIf->hlen = pCIf->if_addrlen; bcopy ((char *) ((struct arpcom *)pCIf)->ac_enaddr, (char *)&pIf->haddr, pIf->hlen); } pDhcpsLeasePool = pDhcpsCfg->pDhcpsLeaseTbl; pDhcpsRelaySourceTbl = pDhcpsCfg->pDhcpsRelayTbl; pDhcpRelayTargetTbl = pDhcpsCfg->pDhcpsTargetTbl; /* read address pool databasae */ status = read_addrpool_db (pDhcpsCfg->dhcpsLeaseTblSize); if (status == ERROR) { dhcpsCleanup (2); return (ERROR); } status = read_addrpool_file (); /* retrieve additional address entries */ if (status == ERROR) { dhcpsCleanup (2); return (ERROR); } status = read_bind_db (); /* read binding database */ if (status == ERROR) { dhcpsCleanup (3); return (ERROR); } /* read database of relay agents */ if (pDhcpsCfg->dhcpsRelayTblSize != 0) read_relay_db (pDhcpsCfg->dhcpsRelayTblSize); /* read database of DHCP servers */ if (pDhcpsCfg->dhcpTargetTblSize != 0) read_server_db (pDhcpsCfg->dhcpTargetTblSize); /* Always use default ports for client and server. */ dhcps_port = htons (pDhcpsCfg->dhcpSPort); dhcpc_port = htons (pDhcpsCfg->dhcpCPort); /* Create a normal socket for sending messages across networks. */ dhcpsIntfaceList->fd = socket (AF_INET, SOCK_DGRAM, 0); if (dhcpsIntfaceList->fd < 0) { dhcpsCleanup (4); return (ERROR); } /* Read-only socket: disable receives to prevent buffer exhaustion. */ result = 0; if (setsockopt (dhcpsIntfaceList->fd, SOL_SOCKET, SO_RCVBUF,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -