📄 dhcpcstate1.c
字号:
/* dhcpcState1.c - DHCP client runtime state machine (lease acquisition) *//* Copyright 1984 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01r,25apr02,wap Only do arp_check() once so DHCPDECLINE messages are sent (SPR #76315)01q,23apr02,wap use dhcpTime() instead of time() (SPR #68900)01p,05nov01,wap Fix memory leak in selecting() (SPR #68981)01o,12oct01,rae merge from truestack (modhist update) note: SPRs 29555 30344 fixed here01n,24oct00,spm fixed modification history after tor3_x merge01m,23oct00,niq merged from version 01p of tor3_x branch (base version 01l); upgrade to BPF replaces tagged frame support01l,04dec97,spm added code review modifications01k,06oct97,spm removed reference to deleted endDriver global01j,02sep97,spm moved data retrieval to prevent dereferenced NULL (SPR #9243); removed excess IMPORT statement01i,26aug97,spm major overhaul: reorganized code and changed user interface to support multiple leases at runtime01h,06aug97,spm removed parameters linked list to reduce memory required01g,10jun97,spm isolated incoming messages in state machine from input hooks01f,02jun97,spm changed DHCP option tags to prevent name conflicts (SPR #8667)01e,06may97,spm changed memory access to align IP header on four byte boundary01d,28apr97,spm corrected placement of conditional include to prevent failure01c,18apr97,spm added conditional include DHCPC_DEBUG for displayed output01b,07apr97,spm added code to use Host Requirements defaults, rewrote docs01a,27jan97,spm extracted from dhcpc.c to reduce object size*//*DESCRIPTIONThis library contains a portion of the finite state machine for the WIDE project DHCP client, modified for vxWorks compatibility.INTERNALThis module contains the functions used prior to the BOUND state. It wascreated to isolate those functions and reduce the size of the boot ROM image so that the DHCP client could be used with targets like the MV147 which have limited ROM capacity. When executing at boot time, the DHCP client's statemachine only used the states defined in this module. After the initial port was completed, the WIDE project implementation was greatly modified to allow the DHCP client library to establish and maintain multiple leases unassociated with the network interface used for message transfer. That capability iscompletely unnecessary for the boot time client, so it no longer shares any code with this module.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 <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 "vxWorks.h"#include "rngLib.h"#include "wdLib.h"#include "time.h"#include "inetLib.h"#include "logLib.h"#include "taskLib.h"#include "sysLib.h"#include "vxLib.h"#include "netLib.h"#include "dhcp/dhcpcStateLib.h"#include "dhcp/dhcpcInternal.h"#include "dhcp/dhcpcCommonLib.h"/* defines *//* Retransmission delay is timer value plus/minus one second (RFC 1541). */#define SLEEP_RANDOM(timer) ( (timer - 1) + (rand () % 2) )#define REQUEST_RETRANS 4 /* Max number of retransmissions (RFC 1541). *//* globals */IMPORT int dhcpcMinLease; /* Minimum accepted lease length. */IMPORT SEM_ID dhcpcMutexSem; /* Protects status indicator */ unsigned char dhcpCookie [MAGIC_LEN] = RFC1048_MAGIC;struct buffer sbuf;int (*fsm [MAX_STATES]) ();int (*handle_param [MAXTAGNUM]) () = { NULL, /* PAD */ handle_ip, /* SUBNET_MASK */ handle_num, /* TIME_OFFSET */ handle_ips, /* ROUTER */ handle_ips, /* TIME_SERVER */ handle_ips, /* NAME_SERVER */ handle_ips, /* DNS_SERVER */ handle_ips, /* LOG_SERVER */ handle_ips, /* COOKIE_SERVER */ handle_ips, /* LPR_SERVER */ handle_ips, /* IMPRESS_SERVER */ handle_ips, /* RLS_SERVER */ handle_str, /* HOSTNAME */ handle_num, /* BOOTSIZE */ handle_str, /* MERIT_DUMP */ handle_str, /* DNS_DOMAIN */ handle_ip, /* SWAP_SERVER */ handle_str, /* ROOT_PATH */ handle_str, /* EXTENSIONS_PATH */ handle_bool, /* IP_FORWARD */ handle_bool, /* NONLOCAL_SRCROUTE */ handle_ippairs, /* POLICY_FILTER */ handle_num, /* MAX_DGRAM_SIZE */ handle_num, /* DEFAULT_IP_TTL */ handle_num, /* MTU_AGING_TIMEOUT */ handle_nums, /* MTU_PLATEAU_TABLE */ handle_num, /* IF_MTU */ handle_bool, /* ALL_SUBNET_LOCAL */ handle_ip, /* BRDCAST_ADDR */ handle_bool, /* MASK_DISCOVER */ handle_bool, /* MASK_SUPPLIER */ handle_bool, /* ROUTER_DISCOVER */ handle_ip, /* ROUTER_SOLICIT */ handle_ippairs, /* STATIC_ROUTE */ handle_bool, /* TRAILER */ handle_num, /* ARP_CACHE_TIMEOUT */ handle_bool, /* ETHER_ENCAP */ handle_num, /* DEFAULT_TCP_TTL */ handle_num, /* KEEPALIVE_INTER */ handle_bool, /* KEEPALIVE_GARBA */ handle_str, /* NIS_DOMAIN */ handle_ips, /* NIS_SERVER */ handle_ips, /* NTP_SERVER */ handle_list, /* VENDOR_SPEC */ handle_ips, /* NBN_SERVER */ handle_ips, /* NBDD_SERVER */ handle_num, /* NB_NODETYPE */ handle_str, /* NB_SCOPE */ handle_ips, /* XFONT_SERVER */ handle_ips, /* XDISPLAY_MANAGER */ NULL, /* REQUEST_IPADDR */ handle_num, /* LEASE_TIME */ NULL, /* OPT_OVERLOAD */ NULL, /* DHCP_MSGTYPE */ handle_ip, /* SERVER_ID */ NULL, /* REQ_LIST */ handle_str, /* DHCP_ERRMSG */ NULL, /* DHCP_MAXMSGSIZE */ handle_num, /* DHCP_T1 */ handle_num, /* DHCP_T2 */ NULL, /* CLASS_ID */ NULL, /* CLIENT_ID */ NULL, NULL, handle_str, /* NISP_DOMAIN */ handle_ips, /* NISP_SERVER */ handle_str, /* TFTP_SERVERNAME */ handle_str, /* BOOTFILE */ handle_ips, /* MOBILEIP_HA */ handle_ips, /* SMTP_SERVER */ handle_ips, /* POP3_SERVER */ handle_ips, /* NNTP_SERVER */ handle_ips, /* DFLT_WWW_SERVER */ handle_ips, /* DFLT_FINGER_SERVER */ handle_ips, /* DFLT_IRC_SERVER */ handle_ips, /* STREETTALK_SERVER */ handle_ips /* STDA_SERVER */ };/********************************************************************************* gen_retransmit - generic retransmission after timeout** This routine retransmits the current DHCP client message (a discover or* a request message) after the appropriate timeout interval expires.* It is called from multiple locations in the finite state machine.** RETURNS: 0 if transmission completed, or negative value on error.** ERRNO: N/A** NOMANUAL*/int gen_retransmit ( LEASE_DATA * pLeaseData, /* lease-specific data structures */ int length /* length of DHCP message */ ) { time_t curr_epoch = 0; struct ifnet * pIf; /* interface used for retransmission */ struct sockaddr_in dest; BOOL bcastFlag; pIf = pLeaseData->ifData.iface; if (dhcpTime (&curr_epoch) == -1) return (-1); /* Update the appropriate fields in the current DHCP message. */ if (pLeaseData->currState != REQUESTING) dhcpcMsgOut.dhcp->secs = htons (curr_epoch - pLeaseData->initEpoch); dhcpcMsgOut.udp->uh_sum = 0; dhcpcMsgOut.udp->uh_sum = udp_cksum (&spudph, (char *)dhcpcMsgOut.udp, ntohs (spudph.ulen)); /* * Retransmit the message. Set the flag to use a link-level broadcast * address if needed (prevents ARP messages if using Ethernet devices). */ bzero ( (char *)&dest, sizeof (struct sockaddr_in)); dest.sin_len = sizeof (struct sockaddr_in); dest.sin_family = AF_INET; dest.sin_addr.s_addr = dhcpcMsgOut.ip->ip_dst.s_addr; if (dest.sin_addr.s_addr == 0xffffffff) bcastFlag = TRUE; else bcastFlag = FALSE; pIf = pLeaseData->ifData.iface; if (dhcpSend (pIf, &dest, sbuf.buf, length, bcastFlag) == ERROR) return (-2); return(0); }/********************************************************************************* retrans_wait_offer - signal reception interval for initial offer expires** This routine sends a timeout notification to the client monitor task when* the interval for receiving an initial lease offer expires. It is called at * interrupt level by a watchdog timer. The monitor task will eventually execute* the WAIT_OFFER state to process the timeout event and retransmit the* DHCP discover message.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void retrans_wait_offer ( LEASE_DATA * pLeaseData /* lease-specific status information */ ) { /* * Ignore the timeout if a state transition occurred during * the scheduled timer interval. */ if (pLeaseData->currState != WAIT_OFFER) return; /* Construct and send a timeout message to the lease monitor task. */ dhcpcEventAdd (DHCP_AUTO_EVENT, DHCP_TIMEOUT, pLeaseData, TRUE); return; }/********************************************************************************* alarm_selecting - signal when collection time expires ** This routine sends a timeout notification to the client monitor task so* that the corresponding lease will stop collecting DHCP offers. It is called * at interrupt level by a watchdog timer. The monitor task will eventually * advance the lease from the SELECTING to the REQUESTING state.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void alarm_selecting ( LEASE_DATA * pLeaseData /* lease-specific status information */ ) { STATUS result; /* * Ignore the timeout if a state transition occurred during * the scheduled timer interval. */ if (pLeaseData->currState != SELECTING) return; /* Construct and send a timeout message to the lease monitor task. */ result = dhcpcEventAdd (DHCP_AUTO_EVENT, DHCP_TIMEOUT, pLeaseData, TRUE);#ifdef DHCPC_DEBUG if (result == ERROR) logMsg ("Warning: couldn't add timeout event for SELECTING state.\n", 0, 0, 0, 0, 0, 0);#endif return; }/********************************************************************************* retrans_requesting - signal when reception interval for initial reply expires** This routine sends a timeout notification to the client monitor task when* the interval for receiving a server reply to a lease request expires. It* is called at interrupt level by a watchdog timer. The monitor task will * eventually execute the REQUESTING state to process the timeout event and * retransmit the DHCP request message.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -