📄 dhcpccommonlib.c
字号:
/* dhcpcCommonLib.c - DHCP client interface shared code library *//* Copyright 1984 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02a,26apr02,wap Update documentation for dhcpcOptionAdd() routine (SPR #73769)01z,23apr02,wap Use BPF_WORDALIGN() when retreiving multiple messages from a BPF buffer (SPR #74215)01y,06dec01,wap Add NPT support01x,16nov01,spm added mod history fix from main branch, ver 01w, base 01v01w,15oct01,rae merge from truestack ver 01z, base 01q (SPR #65264)01v,24may01,mil Bump up dhcp read task stack size to 5000.01u,17nov00,spm added support for BSD Ethernet devices01t,16nov00,spm added required mutual exclusion when sending message01s,24oct00,spm fixed merge from tor3_x branch and updated mod history01r,23oct00,niq merged from version 01w of tor3_x branch (base version 01q); upgrade to BPF replaces tagged frames support01q,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 both the run-timeand boot-time portions of the DHCP client.INCLUDE FILES: dhcpcLib.hSEE ALSO: dhcpcLib*//* includes */#include "dhcp/copyright_dhcp.h"#include "vxWorks.h"#include "wdLib.h"#include "semLib.h"#include "intLib.h"#include "vxLib.h" /* checksum() declaration */#include "tickLib.h" /* tickGet() 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 "net/bpf.h"#include "ipProto.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) *//* globals */int dhcpcDataSock; /* Accesses runtime DHCP messages */BOOL _dhcpcBootFlag = FALSE; /* Data socket available? (only at runtime) */int dhcpcReadTaskId; /* DHCP message retrieval task */LEASE_DATA ** dhcpcLeaseList; /* List of available cookies. */MESSAGE_DATA * dhcpcMessageList; /* Available DHCP messages. */int dhcpcBufSize; /* Maximum supported message size */int dhcpcMaxLeases; /* * Set externally when building runtime image * or to 1 when running boot image. */int dhcpcMinLease; /* Set externally when building image. */int _dhcpcReadTaskPriority = 56; /* Priority level of data retriever */int _dhcpcReadTaskOptions = 0; /* Option settings of data retriever */int _dhcpcReadTaskStackSize = 5000; /* Stack size of data retriever */ /* Berkeley Packet Filter instructions for catching DHCP messages. */struct bpf_insn dhcpfilter[] = { BPF_STMT(BPF_LD+BPF_TYPE,0), /* Save lltype in accumulator */ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 22), /* IP packet? */ /* * The remaining statements use the (new) BPF_HLEN alias to avoid any * link-layer dependencies. The expected destination port and transaction * ID values are altered when necessary by the DHCP routines to match the * actual settings. */ BPF_STMT(BPF_LD+BPF_H+BPF_ABS+BPF_HLEN, 6), /* A <- IP FRAGMENT field */ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 20, 0), /* OFFSET == 0 ? */ BPF_STMT(BPF_LDX+BPF_HLEN, 0), /* X <- frame data offset */ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 9), /* A <- IP_PROTO field */ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_UDP, 0, 17), /* UDP ? */ BPF_STMT(BPF_LD+BPF_HLEN, 0), /* A <- frame data offset */ BPF_STMT(BPF_LDX+BPF_B+BPF_MSH+BPF_HLEN, 0), /* X <- IPHDR LEN field */ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- start of UDP datagram */ BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- start of UDP datagram */ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2), /* A <- UDP DSTPORT */ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 68, 0, 11), /* check DSTPORT */ BPF_STMT(BPF_LD+BPF_H+BPF_ABS+BPF_HLEN, 2), /* A <- IP LEN field */ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 0, 9), /* Correct IP length? */ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 4), /* A <- UDP LEN field */ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 0, 7), /* Correct UDP length? */ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 8), /* A <- DHCP op field */ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, BOOTREPLY, 0, 5), BPF_STMT(BPF_LD+BPF_W+BPF_IND, 12), /* A <- DHCP xid field */ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, -1, 0, 3), /* -1 replaced with real xid */ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 244), /* A <- DHCP options */ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x63825363, 0, 1), /* Matches magic cookie? */ BPF_STMT(BPF_RET+BPF_K+BPF_HLEN, DFLTDHCPLEN + UDPHL + IPHL), /* * ignore data beyond expected * size (some drivers add padding). */ BPF_STMT(BPF_RET+BPF_K, 0) /* unrecognized message: ignore frame */ };struct bpf_program dhcpread = { sizeof (dhcpfilter) / sizeof (struct bpf_insn), dhcpfilter };RING_ID dhcpcEventRing; /* Ring buffer of DHCP events */SEM_ID dhcpcEventSem; /* DHCP event notification *//* forward declarations */UCHAR * dhcpcOptionMerge (UCHAR, UCHAR *, UCHAR *, int);UCHAR * dhcpcOptCreate (UCHAR, UCHAR *, UCHAR *, int);void dhcpcRead (void); /* Retrieve incoming DHCP messages *//********************************************************************************* dhcpcArpSend - transmit an outgoing ARP message** This routine uses the MUX or netif interface to send a frame containing an* ARP packet independently of the link level type. ** RETURNS: OK, or ERROR if send fails.** ERRNO: N/A** NOMANUAL** INTERNAL* Ideally, the dhcpSend() routine would handle any link-level frame* using the registered output routine (ipOutput in the ipProto.c module).* However, constructing frames with the link-level broadcast address* requires significant changes to the MUX/END interface and the ipOutput* routine which are not backward compatible. This routine extracts* relevant portions of the ipOutput routine so that only the driver* layer interface is affected.*/STATUS dhcpcArpSend ( struct ifnet * pIf, /* interface for sending message */ char * pData, /* frame containing ARP packet */ int size /* length of frame, in bytes */ ) { u_short etype; int s; struct mbuf * pMbuf; IP_DRV_CTRL* pDrvCtrl; struct arpcom *ac = (struct arpcom *)pIf; struct ether_header *eh; BOOL bsdFlag = FALSE; /* BSD or END network device? */ pDrvCtrl = (IP_DRV_CTRL *)pIf->pCookie; if (pDrvCtrl == NULL) bsdFlag = TRUE; else if (pDrvCtrl->pIpCookie == NULL) return (ERROR); if ((pIf->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) return (ERROR); pMbuf = bcopy_to_mbufs (pData, size, 0, pIf, NONE); if (pMbuf == NULL) return (ERROR); pIf->if_lastchange = tickGet(); etype = htons (ETHERTYPE_ARP); if (bsdFlag) { /* Build an Ethernet header to the broadcast address. */ M_PREPEND (pMbuf, sizeof (struct ether_header), M_DONTWAIT); if (pMbuf == 0) return (ERROR); eh = mtod (pMbuf, struct ether_header *); pMbuf->mBlkHdr.mFlags |= M_BCAST; /* Always broadcast ARP messages. */ bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type, sizeof(eh->ether_type)); bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, sizeof (etherbroadcastaddr)); bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost, sizeof(eh->ether_shost)); } else { /* * Use the MUX interface to build a frame header. We * need to handle both END and NPT devices here. */ if (pDrvCtrl->nptFlag) { if (pIf->if_addrlen) { M_PREPEND(pMbuf, pIf->if_addrlen, M_DONTWAIT); if (pMbuf == NULL) 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 { pDrvCtrl->pSrc->m_data = (char *)&ac->ac_enaddr; pDrvCtrl->pDst->mBlkHdr.reserved = etype; pDrvCtrl->pSrc->mBlkHdr.reserved = etype; pMbuf->mBlkHdr.mFlags |= M_BCAST; /* Always broadcast ARP messages. */ if ((pMbuf = muxLinkHeaderCreate (pDrvCtrl->pIpCookie, pMbuf, pDrvCtrl->pSrc, pDrvCtrl->pDst, TRUE)) == NULL) return (ERROR); } } s = splimp(); /* * 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); } IF_ENQUEUE(&pIf->if_snd, pMbuf); if ((pIf->if_flags & IFF_OACTIVE) == 0) (*pIf->if_start)(pIf); splx(s); pIf->if_obytes += pMbuf->mBlkHdr.mLen; if (pMbuf->m_flags & M_MCAST || pMbuf->m_flags & M_BCAST) pIf->if_omcasts++; return (OK); }/********************************************************************************* dhcpSend - 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. It also transmits messages* for a BSD Ethernet interface.** RETURNS: OK, or ERROR if send fails.** ERRNO: N/A** INTERNAL* Since the underlying processing performs address resolution, this transmit* routine is only valid when sending messages to a DHCP participant (such* as a server or relay agent) with a known IP address. It cannot send* replies to clients since the hosts will not respond to resolution requests* for the target IP address if it is not yet assigned.** NOMANUAL*/STATUS dhcpSend ( struct ifnet * pIf, /* interface for sending message */ struct sockaddr_in * pDest, /* destination IP address of message */ char * pData, /* IP packet containing DHCP message */ int size, /* amount of data to send */ BOOL broadcastFlag /* broadcast packet? */ ) { struct mbuf * pMbuf; int result; int level;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -