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

📄 dhcpc_subr.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* dhcpc_subr.c - DHCP client general subroutines *//* Copyright 1984 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01u,25apr02,wap  transmit DHCPDECLINEs as broadcasts, not unicasts (SPR                 #75119)01t,23apr02,wap  use dhcpTime() instead of time() (SPR #68900)01s,06dec01,vvv  fixed arp_check again (SPR #69731)01r,12oct01,rae  merge from truestack ver 01x, base 01n                 SPRs 65352, 65264, 70116, 69731, 2742601q,26oct00,spm  fixed byte order of transaction identifier01p,26oct00,spm  fixed modification history after tor3_x merge01o,23oct00,niq  merged from version 01q of tor3_x branch (base version 01n);                 upgrade to BPF replaces tagged frame support01n,01mar99,spm  eliminated creation of invalid route (SPR #24266)01m,04dec97,spm  added code review modifications01l,04dec97,spm  replaced muxDevExists call with test of predefined flag;                 enabled ARP test of intended IP address01k,06oct97,spm  removed reference to deleted endDriver global; replaced with                 support for dynamic driver type detection01j,26aug97,spm  major overhaul: reorganized code and changed user interface                 to support multiple leases at runtime01i,06aug97,spm  renamed class field of dhcp_reqspec structure to prevent C++                 compilation errors (SPR #9079)01h,15jul97,spm  set sa_len and reordered ioctl calls in configuration routine,                 changed to raw sockets to avoid memPartFree error (SPR #8650);                 replaced floating point to prevent ss5 exception (SPR #8738)01g,10jun97,spm  corrected load exception (SPR #8724) and memalign() parameter;                 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,09may97,spm  changed memory access to align IP header on four byte boundary01d,18apr97,spm  added conditional include DHCPC_DEBUG for displayed output,                 shut down interface when changing address/netmask01c,07apr97,spm  corrected bugs extracting options, added safety checks and                 memory cleanup code, rewrote documentation01b,27jan97,spm  added little-endian support and modified to coding standards 01a,03oct96,spm  created by modifying WIDE Project DHCP Implementation*//*DESCRIPTIONThis library contains subroutines which implement several utilities for the Wide project DHCP client, modified for vxWorks compatibility.INTERNALThe routines in this module are called by both portions of the runtime state machine, in the dhcpcState1 and dhcpcState2 modules, which execute before and after a lease is established.INCLUDE_FILES: dhcpcLib.h*//* * WIDE Project DHCP Implementation * Copyright (c) 1995 Akihiro Tominaga * Copyright (c) 1995 WIDE Project * All rights reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided only with the following * conditions are satisfied: * * 1. Both the copyright notice and this permission notice appear in *    all copies of the software, derivative works or modified versions, *    and any portions thereof, and that both notices appear in *    supporting documentation. * 2. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by WIDE Project and *      its contributors. * 3. Neither the name of WIDE Project nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED. * * Feedback of the results generated from any improvements or * extensions made to this software would be much appreciated. * Any such feedback should be sent to: *  *  Akihiro Tominaga *  WIDE Project *  Keio University, Endo 5322, Kanagawa, Japan *  (E-mail: dhcp-dist@wide.ad.jp) * * WIDE project has the rights to redistribute these changes. *//* includes */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <sys/types.h>#include <time.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <net/if.h>#include <net/route.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 <inetLib.h>#include <sysLib.h>#include <logLib.h>#include <sockLib.h>#include <ioLib.h>#include <semLib.h>#include <vxLib.h>#include "muxLib.h"#include "dhcp/dhcp.h"#include "dhcp/dhcpcStateLib.h"#include "dhcp/dhcpcCommonLib.h"#include "dhcp/dhcpcInternal.h"#include "bpfDrv.h"/* globals */    /* Berkeley Packet Filter instructions for catching ARP messages. */LOCAL struct bpf_insn arpfilter[] = {  BPF_STMT(BPF_LD+BPF_TYPE, 0),    /* Save lltype in accumulator */  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_ARP, 0, 9),  /* ARP in frame? */  /*   * The remaining statements use the (new) BPF_HLEN alias to avoid   * any link-layer dependencies.   */  BPF_STMT(BPF_LD+BPF_H+BPF_ABS+BPF_HLEN, 6),    /* A <- ARP OP field */  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARPOP_REPLY, 0, 7),    /* ARP reply ? */  BPF_STMT(BPF_LDX+BPF_HLEN, 0),           /* X <- frame data offset */  BPF_STMT(BPF_LD+BPF_B+BPF_IND, 4),       /* A <- hardware size */  BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),      /* A <- sum of variable offsets */  BPF_STMT(BPF_MISC+BPF_TAX, 0),           /* X <- sum of variable offsets */  BPF_STMT(BPF_LD+BPF_W+BPF_IND, 8),       /* A <- sender IP address */  BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, -1, 0, 1),   /* -1 replaced with real IP */  BPF_STMT(BPF_RET+BPF_K, -1),                     /* copy entire frame */  BPF_STMT(BPF_RET+BPF_K, 0)          /* unrecognized message: ignore frame */  };LOCAL struct bpf_program arpread = {    sizeof (arpfilter) / sizeof (struct bpf_insn),    arpfilter    };IMPORT struct bpf_insn dhcpfilter[];    /* For updating xid test */IMPORT struct bpf_program dhcpread;IMPORT int dhcpcDataSock; 	/* For sending release and renewal messages */IMPORT int flushroutes (void);struct msg dhcpcMsgOut;struct msg dhcpcMsgIn;struct ps_udph spudph;/* locals */LOCAL int bpfArpDev; 			/* Gets any replies to ARP probes. */LOCAL u_short dhcps_port;               /* Server port, in network byte order. */LOCAL u_short dhcpc_port;               /* Client port, in network byte order. *//* forward declarations */int config_if();void set_route();int make_decline (struct dhcp_reqspec *, struct if_info *);int make_release (struct dhcp_reqspec *, struct if_info *, BOOL);long generate_xid (struct if_info *);/********************************************************************************* generate_xid - generate a transaction identifier ** This routine forms a transaction identifier which is used by the lease * for transmissions over the interface described by <pIfData>. The routine * is called from multiple locations after the initialization routines have * retrieved the network interface hardware address.** RETURNS: 32-bit transaction identifier in host byte order. ** ERRNO: N/A** NOMANUAL*/long generate_xid    (    struct if_info * 	pIfData 	/* interface used by lease */    )    {    time_t current = 0;    u_short result1 = 0;    u_short result2 = 0;    u_short result3 = 0;    u_short tmp[6];     bcopy (pIfData->haddr.haddr, (char *)tmp, 6);    dhcpTime (&current);    result1 = checksum (tmp, 6);    result2 = checksum ( (u_short *)&current, 2);    /*     * Although unlikely, it is possible that separate leases which are using     * the same network interface calculate a checksum at the same time. To     * guarantee uniqueness, include the value of the lease-specific pointer     * to the interface descriptor.     */    tmp [0] = ((long)pIfData) >> 16;    tmp [1] = ((long)pIfData) & 0xffff;    result3 = checksum (tmp, 4);    return ( (result1 << 16) + result2 + result3);    }/********************************************************************************* arp_check - use ARP to check if given address is in use** This routine broadcasts an ARP request and waits for a reply to determine if* an IP address offered by a DHCP server is already in use.** RETURNS: ERROR if ARP indicates client in use, or OK otherwise.** ERRNO: N/A** NOMANUAL*/int arp_check    (    struct in_addr *target,     struct if_info *pIfData 	/* interface used by lease */    )    {    int i = 0;    int tmp;    char inbuf [MAX_ARPLEN];    char *pField1;    char *pField2;    struct arphdr * pArpHdr = NULL;    struct ifreq ifr;    struct timeval timeout;    fd_set 	readFds;    bzero (inbuf, MAX_ARPLEN);    pArpHdr = (struct arphdr *) inbuf;    pArpHdr->ar_hrd = htons (pIfData->haddr.htype);    pArpHdr->ar_pro = htons (ETHERTYPE_IP);    pArpHdr->ar_hln = pIfData->haddr.hlen;    pArpHdr->ar_pln = 4;    pArpHdr->ar_op = htons (ARPOP_REQUEST);    /* Set sender H/W address to your address for ARP requests. (RFC 1541). */    pField1 = &inbuf [ARPHL]; 			/* Source hardware address. */    pField2 = pField1 + pArpHdr->ar_hln + 4;    /* Target hardware address. */    for (i = 0; i < pIfData->haddr.hlen; i++)        {        pField1[i] = pIfData->haddr.haddr[i];        pField2[i] = 0;        }    /* Set sender IP address to 0 for ARP requests as per RFC 1541. */    pField1 += pArpHdr->ar_hln;     /* Source IP address. */    pField2 += pArpHdr->ar_hln;     /* Target IP address. */    tmp = 0;    bcopy ( (char *)&tmp, pField1, pArpHdr->ar_pln);    bcopy ( (char *)&target->s_addr, pField2, pArpHdr->ar_pln);    /* Update BPF filter to check for ARP reply from target IP address. */    arpfilter [9].k = htonl (target->s_addr);    if (ioctl (bpfArpDev, BIOCSETF, (int)&arpread) != 0)        return (OK);     /* Ignore errors (permits use of IP address). */    tmp = ARPHL + 2 * (pArpHdr->ar_hln + 4);    /* Size of ARP message. */    /* Set BPF to monitor interface for reply. */    bzero ( (char *)&ifr, sizeof (struct ifreq));    sprintf (ifr.ifr_name, "%s%d", pIfData->iface->if_name,                                   pIfData->iface->if_unit);    if (ioctl (bpfArpDev, BIOCSETIF, (int)&ifr) != 0)        return (OK);     /* Ignore errors (permits use of IP address). */    /*     * Moved dhcpcArpSend after SETIF so that a valid reply received before      * BPF device activation is not missed.     */    dhcpcArpSend (pIfData->iface, inbuf, tmp);    /* Wait one-half second for (unexpected) reply from target IP address. */    timeout.tv_sec = 0;    timeout.tv_usec = 500000;    FD_ZERO (&readFds);    FD_SET (bpfArpDev, &readFds);    tmp = select (bpfArpDev + 1, &readFds, NULL, NULL, &timeout);    /* Disconnect BPF device from input stream until next ARP probe. */    ioctl (bpfArpDev, BIOCSTOP, 0);    if (tmp) 	/* ARP reply received? Duplicate IP address. */        return (ERROR);    else 	/* Timeout occurred - no ARP reply. Probe succeeded. */        return (OK);    }/********************************************************************************* arp_reply - use ARP to notify other hosts of new address in use** This routine broadcasts an ARP reply when the DHCP client changes addresses* to a new value retrieved from a DHCP server.** RETURNS: -1 if ARP indicates client in use, or 0 otherwise.** ERRNO: N/A** NOMANUAL*/int arp_reply    (    struct in_addr *ipaddr,    struct if_info *pIfData 	/* interface used by lease */    )    {    int i = 0;    char inbuf [MAX_ARPLEN];    char *pField1;    char *pField2;    struct arphdr * pArpHdr = NULL;    bzero (inbuf, MAX_ARPLEN);    pArpHdr = (struct arphdr *) inbuf;    pArpHdr->ar_hrd = htons (pIfData->haddr.htype);    pArpHdr->ar_pro = htons (ETHERTYPE_IP);    pArpHdr->ar_hln = pIfData->haddr.hlen;    pArpHdr->ar_pln = 4;    pArpHdr->ar_op = htons (ARPOP_REPLY);    /*     * Set sender and target H/W addresses to your address     * for sending an unsolicited reply.     */    pField1 = &inbuf [ARPHL];                   /* Source hardware address. */    pField2 = pField1 + pArpHdr->ar_hln + 4;    /* Target hardware address. */    for (i = 0; i < pIfData->haddr.hlen; i++)        {        pField1[i] = pField2[i] = pIfData->haddr.haddr[i];        }    /*     * Set sender and target IP address to given value     * to announce new IP address usage.     */    pField1 += pArpHdr->ar_hln;     /* Source IP address. */    pField2 += pArpHdr->ar_hln;     /* Target IP address. */    bcopy ( (char *)&ipaddr->s_addr, pField1, pArpHdr->ar_pln);    bcopy ( (char *)&ipaddr->s_addr, pField2, pArpHdr->ar_pln);    /* Broadcast unsolicited reply to notify all hosts of new IP address. */    i = ARPHL + 2 * (pArpHdr->ar_hln + 4);    /* Size of ARP message. */    dhcpcArpSend (pIfData->iface, inbuf, i);    return (0);    }/********************************************************************************* nvttostr - convert NVT ASCII to strings** This routine implements a limited NVT conversion which removes any embedded* NULL characters from the input string.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/int nvttostr    (    char *	nvt,     char *	str,    int 	length    )    {    FAST int i = 0;    FAST char *tmp = NULL;

⌨️ 快捷键说明

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