📄 dhcpccommonlib.c
字号:
/* dhcpcCommonLib.c - DHCP client interface shared code library *//* Copyright 1984 - 1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history____________________01q,16mar99,spm recovered orphaned code from tor1_0_1.sens1_1 (SPR #25770)01p,06oct98,spm fixed copying of parameters with IP address pairs (SPR #22416)01o,04dec97,spm added code review modifications01n,06oct97,spm removed reference to deleted endDriver global; replaced with support for dynamic driver type detection01m,30sep97,kbw fixed minor spelling error in library man page01l,02sep97,spm modified handling of fatal errors - corrected conditions for disabling network interface and added event hook execution01k,26aug97,spm major overhaul: reorganized code and changed user interface to support multiple leases at runtime01j,06aug97,spm removed parameters linked list to reduce memory required; renamed class field of dhcp_reqspec structure to prevent C++ compilation errors (SPR #9079); corrected minor errors in man pages introduced by 01i revision01i,30jul97,kbw fixed man page problems found in beta review01h,15jul97,spm cleaned up man pages01g,10jun97,spm moved length test to prevent buffer overflow and isolated incoming messages in state machine from input hooks01f,02jun97,spm changed DHCP option tags to prevent name conflicts (SPR #8667) and updated man pages01e,06may97,spm changed memory access to align IP header on four byte boundary01d,15apr97,kbw fixing man page format and wording01c,07apr97,spm added code to use Host Requirements defaults and cleanup memory on exit, fixed bugs caused by Ethernet trailers, eliminated potential buffer overruns, rewrote documentation01b,29jan97,spm added END driver support and modified to fit coding standards01a,14nov96,spm created from shared functions of dhcpcLib.c and dhcpcBootLib.c*//*DESCRIPTIONThis library contains the shared functions used by the run-time versionof the DHCP client both before and after a lease is established.INCLUDE FILES: dhcpcLib.hSEE ALSO: dhcpcLib*//* includes */#include "dhcp/copyright_dhcp.h"#include "vxWorks.h"#include "wdLib.h"#include "semLib.h"#include "etherLib.h"#include "rngLib.h"#include "intLib.h"#include "vxLib.h" /* checksum() declaration */#include "muxLib.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <signal.h>#include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <net/if.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/if_ether.h>#include <netinet/ip.h>#include <netinet/udp.h>#include <arpa/inet.h> #include "dhcp/dhcpcCommonLib.h"#include "dhcp/dhcpcStateLib.h"#include "dhcp/dhcpc.h"#include "dhcp/dhcpcInternal.h"/* defines */#define _BYTESPERWORD 4 /* Conversion factor for IP header */ /* Host requirements documents default values. */#define _HRD_MAX_DGRAM 576 /* Default maximum datagram size. */#define _HRD_IP_TTL 64 /* Default IP time-to-live (seconds) */#define _HRD_MTU 576 /* Default interface MTU */#define _HRD_ROUTER 0xffffffff /* Default router solication */ /* address - 255.255.255.255 */#define _HRD_ARP_TIME 60 /* Default ARP cache timeout (seconds) */#define _HRD_TCP_TTL 64 /* Default TCP time-to-live (seconds) */#define _HRD_TCP_TIME 7200 /* Default TCP keepalive interval (seconds) *//* externals */IMPORT SEM_ID dhcpcMutexSem; /* Protects the DHCP status indicator *//* globals */struct interface dhcpif;WDOG_ID dhcpcEventTimer; /* Timeout for DHCP events */RING_ID dhcpcEventRing; /* Ring buffer of DHCP events */RING_ID dhcpcMsgRing; /* Ring buffer of DHCP messages */SEM_ID dhcpcEventSem; /* DHCP event notification */struct msg dhcpcIfMsg; /* Incoming DHCP message components */char * pDhcpcRecvBuf; /* Message buffer for state machine. */SEM_ID dhcpcArpEventSem; /* ARP reply notification */u_char dhcpArpSpa [4]; /* Sender protocol address for ARP replies */struct if_info dhcpcDevice; /* Specifies underlying hardware *//* locals */LOCAL char inputBuffer [ETHERHL + sizeof (struct ether_arp)]; /* ARP replies *//* forward declarations */void dhcpcMon (void); /* Monitor lease */BOOL dhcpcInputHook (struct ifnet *, char *, int);LOCAL STATUS dhcpcEventGet (EVENT_DATA *);LOCAL STATUS dhcpcEventHandle (EVENT_DATA *);char *dhcpcOptionFind (LEASE_DATA *, int, int *); /* Locate option */LOCAL void dhcpcCleanup (void);/********************************************************************************* dhcpcMon - monitor all DHCP client activity** This routine establishes and monitors all DHCP leases. It receives all DHCP* event notifications (message arrivals, timeouts, and user requests), and * controls the event processing by invoking the appropriate routines. * It is the entry point for the monitor task created during the library* initialization and should only be called internally.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void dhcpcMon (void) { int offset; int level; struct ifnet * pIf; EVENT_DATA newEvent; STATUS result; BOOL bsdDrvFlag = TRUE; /* * Intercept all incoming DHCP messages for any interface. Currently, * the same input hook routine must be added once for all BSD drivers, * if any, and once for each END-style driver, since the library cannot * anticipate which interfaces will be used. Eventually we will be able * to register DHCP as a protocol and eliminate the use of input hooks. * At that point, we won't need this messy access to the global interface * list. */ level = splnet (); for (pIf = ifnet; pIf != NULL; pIf = pIf->if_next) { if (strcmp (pIf->if_name, "lo") == 0) /* Skip loopback interfaces. */ continue; if (muxDevExists (pIf->if_name, pIf->if_unit)) etherInputHookAdd (dhcpcInputHook, pIf->if_name, pIf->if_unit); else if (bsdDrvFlag) { /* Only set one input hook for all BSD drivers. */ etherInputHookAdd (dhcpcInputHook, NULL, pIf->if_unit); bsdDrvFlag = FALSE; } } splx (level); FOREVER { /* Wait for an incoming DHCP message, user request, or timeout. */ result = dhcpcEventGet (&newEvent); if (result == ERROR) { /* Invalid or missing event - ignore. */ continue; } /* Handle dhcpcShutdown() requests. */ if (newEvent.source == DHCP_USER_EVENT && newEvent.type == DHCP_USER_SHUTDOWN) { /* Release all active leases, free all memory, and exit. */ newEvent.type = DHCP_USER_RELEASE; for (offset = 0; offset < dhcpcMaxLeases; offset++) { if (dhcpcLeaseList [offset] != NULL) { newEvent.leaseId = dhcpcLeaseList [offset]; dhcpcEventHandle (&newEvent); dhcpcLeaseList [offset] = NULL; } } dhcpcCleanup (); break; } /* Process all other events in the context of the target lease. */ result = dhcpcEventHandle (&newEvent); if (result == DHCPC_DONE) { /* Set the list entry to NULL when a lease is removed. */ for (offset = 0; offset < dhcpcMaxLeases; offset++) { if (dhcpcLeaseList [offset] == newEvent.leaseId) { dhcpcLeaseList [offset] = NULL; free (newEvent.leaseId); break; } } } } /* The monitor task only returns in response to a dhcpcShutdown() call. */ return; }/********************************************************************************* dhcpcEventGet - wait for a DHCP event** This routine retrieves DHCP events for processing by the monitor task.* If the contents of the event descriptor are valid, it is stored in the* buffer provided by the <pNewEvent> parameter. Automatic event descriptors* are created when a DHCP message arrives or a timeout expires. Manual* event descriptors are generated by calls to the dhcpBind(), dhcpVerify(), * dhcpRelease() and dhcpShutdown() routines.** RETURNS: OK if valid event retrieved, or ERROR otherwise.** ERRNO: N/A** NOMANUAL*/LOCAL STATUS dhcpcEventGet ( EVENT_DATA * pNewEvent /* pointer to event descriptor */ ) { STATUS result; int status; int offset; LEASE_DATA * pLeaseData; /* Wait for event occurrence. */ semTake (dhcpcEventSem, WAIT_FOREVER); /* Retrieve event from message ring. */ if (rngIsEmpty (dhcpcEventRing) == TRUE) {#ifdef DHCPC_DEBUG logMsg ("dhcpcEventGet: Notification empty.\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } status = rngBufGet (dhcpcEventRing, (char *)pNewEvent, sizeof (EVENT_DATA)); if (status != sizeof (EVENT_DATA)) {#ifdef DHCPC_DEBUG logMsg ("dhcpcEventGet: Notification error.\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } /* * Check event descriptor for valid data. The primary purpose of * this code is to catalog all the possible event descriptors * in one location, since invalid data could only result from a failure * in memory-to-memory copies by the ring buffers, which is extremely * unlikely. Even if that occurred, the DHCP protocol is designed to * handle any errors in message arrival notifications as a byproduct of * UDP processing, but corruption of timeout or user events could result * in unrecoverable errors. */ result = OK; switch (pNewEvent->source) { case DHCP_AUTO_EVENT: /* Validate automatic event types. */ if (pNewEvent->type != DHCP_TIMEOUT && pNewEvent->type != DHCP_MSG_ARRIVED) { result = ERROR; } break; case DHCP_USER_EVENT: /* Validate manual event types. */ if (pNewEvent->type != DHCP_USER_BIND && pNewEvent->type != DHCP_USER_VERIFY && pNewEvent->type != DHCP_USER_RELEASE && pNewEvent->type != DHCP_USER_SHUTDOWN) { result = ERROR; } break; default: /* Unknown event class. */ result = ERROR; break; } if (result == ERROR) return (ERROR); /* Lease identifiers must be checked for all events except shutdown. */ if (pNewEvent->source == DHCP_USER_EVENT && pNewEvent->type == DHCP_USER_SHUTDOWN) return (OK); /* * Remove any message from the message ring, regardless of lease ID. * Store in receive buffer at offset to provide 4-byte alignment of * IP header needed by Sun BSP's. */ if (pNewEvent->source == DHCP_AUTO_EVENT && pNewEvent->type == DHCP_MSG_ARRIVED) { /* * Ignore events with bad messages - the protocol will eventually * timeout if no valid message arrives. */ status = rngBufGet (dhcpcMsgRing, &pDhcpcRecvBuf [DHCPC_OFF], pNewEvent->length); if (status != pNewEvent->length) return (ERROR); } /* * Although not likely, a lease could be released between the * arrival of an event and the event processing. In that case, * the recorded lease identifier will be invalid. Ignore those events. */ pLeaseData = pNewEvent->leaseId; for (offset = 0; offset < dhcpcMaxLeases; offset++) if (dhcpcLeaseList [offset] != NULL && dhcpcLeaseList [offset] == pLeaseData) break; if (offset == dhcpcMaxLeases) return (ERROR); return (result); }/********************************************************************************* dhcpcEventHandle - process a DHCP event for a particular lease** This routine executes a portion of the DHCP client finite state machine * until a DHCP message is sent and/or the relevant timeouts are set. It * processes all incoming DHCP messages, timeouts, and all user requests * except for the dhcpcShutdown() routine. All handled events are processed * in the context of the current state of a known lease. It is invoked by the * monitor task when the events occur, and should only be called internally.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -