Import the OpenBSD dhclient as shipped with OpenBSD-3.7 (the tag
OPENBSD_3_7).
This commit is contained in:
parent
a9c7144e7a
commit
47c0859616
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/OpenBSD/dist/; revision=147072
@ -1,30 +1,48 @@
|
|||||||
# ex:ts=8
|
# $OpenBSD: Makefile,v 1.9 2004/05/04 12:52:05 henning Exp $
|
||||||
#
|
#
|
||||||
# @(#)Makefile 1.0 (obrien) 2/6/99
|
# Copyright (c) 1996, 1997 The Internet Software Consortium.
|
||||||
# $Id$
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 by David O'Brien
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# This file is under a "FreeBSD" copyright. See /usr/src/sys/sys/copyright.h
|
# modification, are permitted provided that the following conditions
|
||||||
# for the terms of the copyright.
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
# THE INTERNET SOFTWARE CONSORTIUM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
|
|
||||||
.PATH: ${.CURDIR}/../../contrib/isc-dhcp/client ${.CURDIR}/../../contrib/isc-dhcp/common
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
SRCS= dhclient.c clparse.c alloc.c dispatch.c hash.c bpf.c options.c \
|
||||||
|
tree.c conflex.c errwarn.c inet.c packet.c convert.c tables.c \
|
||||||
|
parse.c privsep.c
|
||||||
|
|
||||||
PROG= dhclient
|
PROG= dhclient
|
||||||
MAN5= dhclient.conf.5 dhclient.leases.5 dhcp-options.5
|
MAN= dhclient.8 dhclient.conf.5 dhclient.leases.5 dhclient-script.8
|
||||||
MAN8= dhclient.8 dhclient-script.8
|
|
||||||
|
|
||||||
SRCS= dhclient.c clparse.c
|
CFLAGS+=-Wall
|
||||||
SRCS+= raw.c parse.c nit.c icmp.c dispatch.c conflex.c upf.c bpf.c \
|
|
||||||
socket.c packet.c memory.c print.c options.c inet.c convert.c \
|
|
||||||
tree.c tables.c hash.c alloc.c errwarn.c inet_addr.c
|
|
||||||
|
|
||||||
CFLAGS+= -I${.CURDIR}/../../contrib/isc-dhcp/includes \
|
beforeinstall:
|
||||||
-I${.CURDIR}/../../contrib/isc-dhcp
|
${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
|
||||||
|
${.CURDIR}/dhclient-script ${DESTDIR}/sbin/dhclient-script
|
||||||
afterinstall:
|
|
||||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
|
|
||||||
${.CURDIR}/../../contrib/isc-dhcp/client/scripts/freebsd \
|
|
||||||
${BINDIR}/dhclient-script
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
76
sbin/dhclient/alloc.c
Normal file
76
sbin/dhclient/alloc.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* $OpenBSD: alloc.c,v 1.9 2004/05/04 20:28:40 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Memory allocation... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
struct string_list *
|
||||||
|
new_string_list(size_t size)
|
||||||
|
{
|
||||||
|
struct string_list *rval;
|
||||||
|
|
||||||
|
rval = calloc(1, sizeof(struct string_list) + size);
|
||||||
|
if (rval != NULL)
|
||||||
|
rval->string = ((char *)rval) + sizeof(struct string_list);
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hash_table *
|
||||||
|
new_hash_table(int count)
|
||||||
|
{
|
||||||
|
struct hash_table *rval;
|
||||||
|
|
||||||
|
rval = calloc(1, sizeof(struct hash_table) -
|
||||||
|
(DEFAULT_HASH_SIZE * sizeof(struct hash_bucket *)) +
|
||||||
|
(count * sizeof(struct hash_bucket *)));
|
||||||
|
if (rval == NULL)
|
||||||
|
return (NULL);
|
||||||
|
rval->hash_count = count;
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hash_bucket *
|
||||||
|
new_hash_bucket(void)
|
||||||
|
{
|
||||||
|
struct hash_bucket *rval = calloc(1, sizeof(struct hash_bucket));
|
||||||
|
|
||||||
|
return (rval);
|
||||||
|
}
|
374
sbin/dhclient/bpf.c
Normal file
374
sbin/dhclient/bpf.c
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
/* $OpenBSD: bpf.c,v 1.13 2004/05/05 14:28:58 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* BPF socket interface code, originally contributed by Archie Cobbs. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1998, 1999
|
||||||
|
* The Internet Software Consortium. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
#include <net/bpf.h>
|
||||||
|
#include <netinet/in_systm.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <netinet/udp.h>
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
|
||||||
|
#define BPF_FORMAT "/dev/bpf%d"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by get_interface_list for each interface that's discovered.
|
||||||
|
* Opens a packet filter for each interface and adds it to the select
|
||||||
|
* mask.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
if_register_bpf(struct interface_info *info)
|
||||||
|
{
|
||||||
|
char filename[50];
|
||||||
|
int sock, b;
|
||||||
|
|
||||||
|
/* Open a BPF device */
|
||||||
|
for (b = 0; 1; b++) {
|
||||||
|
snprintf(filename, sizeof(filename), BPF_FORMAT, b);
|
||||||
|
sock = open(filename, O_RDWR, 0);
|
||||||
|
if (sock < 0) {
|
||||||
|
if (errno == EBUSY)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
error("Can't find free bpf: %m");
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the BPF device to point at this interface. */
|
||||||
|
if (ioctl(sock, BIOCSETIF, info->ifp) < 0)
|
||||||
|
error("Can't attach interface %s to bpf device %s: %m",
|
||||||
|
info->name, filename);
|
||||||
|
|
||||||
|
return (sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
if_register_send(struct interface_info *info)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we're using the bpf API for sending and receiving, we
|
||||||
|
* don't need to register this interface twice.
|
||||||
|
*/
|
||||||
|
info->wfdesc = info->rfdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Packet filter program...
|
||||||
|
*
|
||||||
|
* XXX: Changes to the filter program may require changes to the
|
||||||
|
* constant offsets used in if_register_send to patch the BPF program!
|
||||||
|
*/
|
||||||
|
struct bpf_insn dhcp_bpf_filter[] = {
|
||||||
|
/* Make sure this is an IP packet... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
|
||||||
|
|
||||||
|
/* Make sure it's a UDP packet... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
|
||||||
|
|
||||||
|
/* Make sure this isn't a fragment... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
|
||||||
|
|
||||||
|
/* Get the IP header length... */
|
||||||
|
BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14),
|
||||||
|
|
||||||
|
/* Make sure it's to the right port... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */
|
||||||
|
|
||||||
|
/* If we passed all the tests, ask for the whole packet. */
|
||||||
|
BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
|
||||||
|
|
||||||
|
/* Otherwise, drop it. */
|
||||||
|
BPF_STMT(BPF_RET+BPF_K, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
int dhcp_bpf_filter_len = sizeof(dhcp_bpf_filter) / sizeof(struct bpf_insn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Packet write filter program:
|
||||||
|
* 'ip and udp and src port bootps and dst port (bootps or bootpc)'
|
||||||
|
*/
|
||||||
|
struct bpf_insn dhcp_bpf_wfilter[] = {
|
||||||
|
BPF_STMT(BPF_LD + BPF_B + BPF_IND, 14),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (IPVERSION << 4) + 5, 0, 12),
|
||||||
|
|
||||||
|
/* Make sure this is an IP packet... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 10),
|
||||||
|
|
||||||
|
/* Make sure it's a UDP packet... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8),
|
||||||
|
|
||||||
|
/* Make sure this isn't a fragment... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 6, 0), /* patched */
|
||||||
|
|
||||||
|
/* Get the IP header length... */
|
||||||
|
BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14),
|
||||||
|
|
||||||
|
/* Make sure it's from the right port... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 14),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 68, 0, 3),
|
||||||
|
|
||||||
|
/* Make sure it is to the right ports ... */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16),
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
|
||||||
|
|
||||||
|
/* If we passed all the tests, ask for the whole packet. */
|
||||||
|
BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
|
||||||
|
|
||||||
|
/* Otherwise, drop it. */
|
||||||
|
BPF_STMT(BPF_RET+BPF_K, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
int dhcp_bpf_wfilter_len = sizeof(dhcp_bpf_wfilter) / sizeof(struct bpf_insn);
|
||||||
|
|
||||||
|
void
|
||||||
|
if_register_receive(struct interface_info *info)
|
||||||
|
{
|
||||||
|
struct bpf_version v;
|
||||||
|
struct bpf_program p;
|
||||||
|
int flag = 1, sz;
|
||||||
|
|
||||||
|
/* Open a BPF device and hang it on this interface... */
|
||||||
|
info->rfdesc = if_register_bpf(info);
|
||||||
|
|
||||||
|
/* Make sure the BPF version is in range... */
|
||||||
|
if (ioctl(info->rfdesc, BIOCVERSION, &v) < 0)
|
||||||
|
error("Can't get BPF version: %m");
|
||||||
|
|
||||||
|
if (v.bv_major != BPF_MAJOR_VERSION ||
|
||||||
|
v.bv_minor < BPF_MINOR_VERSION)
|
||||||
|
error("Kernel BPF version out of range - recompile dhcpd!");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set immediate mode so that reads return as soon as a packet
|
||||||
|
* comes in, rather than waiting for the input buffer to fill
|
||||||
|
* with packets.
|
||||||
|
*/
|
||||||
|
if (ioctl(info->rfdesc, BIOCIMMEDIATE, &flag) < 0)
|
||||||
|
error("Can't set immediate mode on bpf device: %m");
|
||||||
|
|
||||||
|
/* Get the required BPF buffer length from the kernel. */
|
||||||
|
if (ioctl(info->rfdesc, BIOCGBLEN, &sz) < 0)
|
||||||
|
error("Can't get bpf buffer length: %m");
|
||||||
|
info->rbuf_max = sz;
|
||||||
|
info->rbuf = malloc(info->rbuf_max);
|
||||||
|
if (!info->rbuf)
|
||||||
|
error("Can't allocate %lu bytes for bpf input buffer.",
|
||||||
|
(unsigned long)info->rbuf_max);
|
||||||
|
info->rbuf_offset = 0;
|
||||||
|
info->rbuf_len = 0;
|
||||||
|
|
||||||
|
/* Set up the bpf filter program structure. */
|
||||||
|
p.bf_len = dhcp_bpf_filter_len;
|
||||||
|
p.bf_insns = dhcp_bpf_filter;
|
||||||
|
|
||||||
|
/* Patch the server port into the BPF program...
|
||||||
|
*
|
||||||
|
* XXX: changes to filter program may require changes to the
|
||||||
|
* insn number(s) used below!
|
||||||
|
*/
|
||||||
|
dhcp_bpf_filter[8].k = LOCAL_PORT;
|
||||||
|
|
||||||
|
if (ioctl(info->rfdesc, BIOCSETF, &p) < 0)
|
||||||
|
error("Can't install packet filter program: %m");
|
||||||
|
|
||||||
|
/* Set up the bpf write filter program structure. */
|
||||||
|
p.bf_len = dhcp_bpf_wfilter_len;
|
||||||
|
p.bf_insns = dhcp_bpf_wfilter;
|
||||||
|
|
||||||
|
if (dhcp_bpf_wfilter[7].k == 0x1fff)
|
||||||
|
dhcp_bpf_wfilter[7].k = htons(IP_MF|IP_OFFMASK);
|
||||||
|
|
||||||
|
if (ioctl(info->rfdesc, BIOCSETWF, &p) < 0)
|
||||||
|
error("Can't install write filter program: %m");
|
||||||
|
|
||||||
|
if (ioctl(info->rfdesc, BIOCLOCK, NULL) < 0)
|
||||||
|
error("Cannot lock bpf");
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
send_packet(struct interface_info *interface, struct dhcp_packet *raw,
|
||||||
|
size_t len, struct in_addr from, struct sockaddr_in *to,
|
||||||
|
struct hardware *hto)
|
||||||
|
{
|
||||||
|
unsigned char buf[256];
|
||||||
|
struct iovec iov[2];
|
||||||
|
int result, bufp = 0;
|
||||||
|
|
||||||
|
/* Assemble the headers... */
|
||||||
|
assemble_hw_header(interface, buf, &bufp, hto);
|
||||||
|
assemble_udp_ip_header(buf, &bufp, from.s_addr,
|
||||||
|
to->sin_addr.s_addr, to->sin_port, (unsigned char *)raw, len);
|
||||||
|
|
||||||
|
/* Fire it off */
|
||||||
|
iov[0].iov_base = (char *)buf;
|
||||||
|
iov[0].iov_len = bufp;
|
||||||
|
iov[1].iov_base = (char *)raw;
|
||||||
|
iov[1].iov_len = len;
|
||||||
|
|
||||||
|
result = writev(interface->wfdesc, iov, 2);
|
||||||
|
if (result < 0)
|
||||||
|
warning("send_packet: %m");
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
receive_packet(struct interface_info *interface, unsigned char *buf,
|
||||||
|
size_t len, struct sockaddr_in *from, struct hardware *hfrom)
|
||||||
|
{
|
||||||
|
int length = 0, offset = 0;
|
||||||
|
struct bpf_hdr hdr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All this complexity is because BPF doesn't guarantee that
|
||||||
|
* only one packet will be returned at a time. We're getting
|
||||||
|
* what we deserve, though - this is a terrible abuse of the BPF
|
||||||
|
* interface. Sigh.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Process packets until we get one we can return or until we've
|
||||||
|
* done a read and gotten nothing we can return...
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
/* If the buffer is empty, fill it. */
|
||||||
|
if (interface->rbuf_offset == interface->rbuf_len) {
|
||||||
|
length = read(interface->rfdesc, interface->rbuf,
|
||||||
|
interface->rbuf_max);
|
||||||
|
if (length <= 0)
|
||||||
|
return (length);
|
||||||
|
interface->rbuf_offset = 0;
|
||||||
|
interface->rbuf_len = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there isn't room for a whole bpf header, something
|
||||||
|
* went wrong, but we'll ignore it and hope it goes
|
||||||
|
* away... XXX
|
||||||
|
*/
|
||||||
|
if (interface->rbuf_len - interface->rbuf_offset <
|
||||||
|
sizeof(hdr)) {
|
||||||
|
interface->rbuf_offset = interface->rbuf_len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy out a bpf header... */
|
||||||
|
memcpy(&hdr, &interface->rbuf[interface->rbuf_offset],
|
||||||
|
sizeof(hdr));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the bpf header plus data doesn't fit in what's
|
||||||
|
* left of the buffer, stick head in sand yet again...
|
||||||
|
*/
|
||||||
|
if (interface->rbuf_offset + hdr.bh_hdrlen + hdr.bh_caplen >
|
||||||
|
interface->rbuf_len) {
|
||||||
|
interface->rbuf_offset = interface->rbuf_len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the captured data wasn't the whole packet, or if
|
||||||
|
* the packet won't fit in the input buffer, all we can
|
||||||
|
* do is drop it.
|
||||||
|
*/
|
||||||
|
if (hdr.bh_caplen != hdr.bh_datalen) {
|
||||||
|
interface->rbuf_offset += hdr.bh_hdrlen = hdr.bh_caplen;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip over the BPF header... */
|
||||||
|
interface->rbuf_offset += hdr.bh_hdrlen;
|
||||||
|
|
||||||
|
/* Decode the physical header... */
|
||||||
|
offset = decode_hw_header(interface->rbuf,
|
||||||
|
interface->rbuf_offset, hfrom);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a physical layer checksum failed (dunno of any
|
||||||
|
* physical layer that supports this, but WTH), skip
|
||||||
|
* this packet.
|
||||||
|
*/
|
||||||
|
if (offset < 0) {
|
||||||
|
interface->rbuf_offset += hdr.bh_caplen;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
interface->rbuf_offset += offset;
|
||||||
|
hdr.bh_caplen -= offset;
|
||||||
|
|
||||||
|
/* Decode the IP and UDP headers... */
|
||||||
|
offset = decode_udp_ip_header(interface->rbuf,
|
||||||
|
interface->rbuf_offset, from, NULL, hdr.bh_caplen);
|
||||||
|
|
||||||
|
/* If the IP or UDP checksum was bad, skip the packet... */
|
||||||
|
if (offset < 0) {
|
||||||
|
interface->rbuf_offset += hdr.bh_caplen;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
interface->rbuf_offset += offset;
|
||||||
|
hdr.bh_caplen -= offset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there's not enough room to stash the packet data,
|
||||||
|
* we have to skip it (this shouldn't happen in real
|
||||||
|
* life, though).
|
||||||
|
*/
|
||||||
|
if (hdr.bh_caplen > len) {
|
||||||
|
interface->rbuf_offset += hdr.bh_caplen;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy out the data in the packet... */
|
||||||
|
memcpy(buf, interface->rbuf + interface->rbuf_offset,
|
||||||
|
hdr.bh_caplen);
|
||||||
|
interface->rbuf_offset += hdr.bh_caplen;
|
||||||
|
return (hdr.bh_caplen);
|
||||||
|
} while (!length);
|
||||||
|
return (0);
|
||||||
|
}
|
938
sbin/dhclient/clparse.c
Normal file
938
sbin/dhclient/clparse.c
Normal file
@ -0,0 +1,938 @@
|
|||||||
|
/* $OpenBSD: clparse.c,v 1.18 2004/09/15 18:15:18 henning Exp $ */
|
||||||
|
|
||||||
|
/* Parser for dhclient config and lease files... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1997 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
#include "dhctoken.h"
|
||||||
|
|
||||||
|
struct client_config top_level_config;
|
||||||
|
struct interface_info *dummy_interfaces;
|
||||||
|
extern struct interface_info *ifi;
|
||||||
|
|
||||||
|
char client_script_name[] = "/sbin/dhclient-script";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* client-conf-file :== client-declarations EOF
|
||||||
|
* client-declarations :== <nil>
|
||||||
|
* | client-declaration
|
||||||
|
* | client-declarations client-declaration
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
read_client_conf(void)
|
||||||
|
{
|
||||||
|
FILE *cfile;
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
struct client_config *config;
|
||||||
|
|
||||||
|
new_parse(path_dhclient_conf);
|
||||||
|
|
||||||
|
/* Set up the initial dhcp option universe. */
|
||||||
|
initialize_universes();
|
||||||
|
|
||||||
|
/* Initialize the top level client configuration. */
|
||||||
|
memset(&top_level_config, 0, sizeof(top_level_config));
|
||||||
|
|
||||||
|
/* Set some defaults... */
|
||||||
|
top_level_config.timeout = 60;
|
||||||
|
top_level_config.select_interval = 0;
|
||||||
|
top_level_config.reboot_timeout = 10;
|
||||||
|
top_level_config.retry_interval = 300;
|
||||||
|
top_level_config.backoff_cutoff = 15;
|
||||||
|
top_level_config.initial_interval = 3;
|
||||||
|
top_level_config.bootp_policy = ACCEPT;
|
||||||
|
top_level_config.script_name = client_script_name;
|
||||||
|
top_level_config.requested_options
|
||||||
|
[top_level_config.requested_option_count++] = DHO_SUBNET_MASK;
|
||||||
|
top_level_config.requested_options
|
||||||
|
[top_level_config.requested_option_count++] = DHO_BROADCAST_ADDRESS;
|
||||||
|
top_level_config.requested_options
|
||||||
|
[top_level_config.requested_option_count++] = DHO_TIME_OFFSET;
|
||||||
|
top_level_config.requested_options
|
||||||
|
[top_level_config.requested_option_count++] = DHO_ROUTERS;
|
||||||
|
top_level_config.requested_options
|
||||||
|
[top_level_config.requested_option_count++] = DHO_DOMAIN_NAME;
|
||||||
|
top_level_config.requested_options
|
||||||
|
[top_level_config.requested_option_count++] =
|
||||||
|
DHO_DOMAIN_NAME_SERVERS;
|
||||||
|
top_level_config.requested_options
|
||||||
|
[top_level_config.requested_option_count++] = DHO_HOST_NAME;
|
||||||
|
|
||||||
|
if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
|
||||||
|
do {
|
||||||
|
token = peek_token(&val, cfile);
|
||||||
|
if (token == EOF)
|
||||||
|
break;
|
||||||
|
parse_client_statement(cfile, NULL, &top_level_config);
|
||||||
|
} while (1);
|
||||||
|
token = next_token(&val, cfile); /* Clear the peek buffer */
|
||||||
|
fclose(cfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up state and config structures for clients that don't
|
||||||
|
* have per-interface configuration declarations.
|
||||||
|
*/
|
||||||
|
config = NULL;
|
||||||
|
if (!ifi->client) {
|
||||||
|
ifi->client = malloc(sizeof(struct client_state));
|
||||||
|
if (!ifi->client)
|
||||||
|
error("no memory for client state.");
|
||||||
|
memset(ifi->client, 0, sizeof(*(ifi->client)));
|
||||||
|
}
|
||||||
|
if (!ifi->client->config) {
|
||||||
|
if (!config) {
|
||||||
|
config = malloc(sizeof(struct client_config));
|
||||||
|
if (!config)
|
||||||
|
error("no memory for client config.");
|
||||||
|
memcpy(config, &top_level_config,
|
||||||
|
sizeof(top_level_config));
|
||||||
|
}
|
||||||
|
ifi->client->config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (!warnings_occurred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lease-file :== client-lease-statements EOF
|
||||||
|
* client-lease-statements :== <nil>
|
||||||
|
* | client-lease-statements LEASE client-lease-statement
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
read_client_leases(void)
|
||||||
|
{
|
||||||
|
FILE *cfile;
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
|
||||||
|
new_parse(path_dhclient_db);
|
||||||
|
|
||||||
|
/* Open the lease file. If we can't open it, just return -
|
||||||
|
we can safely trust the server to remember our state. */
|
||||||
|
if ((cfile = fopen(path_dhclient_db, "r")) == NULL)
|
||||||
|
return;
|
||||||
|
do {
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token == EOF)
|
||||||
|
break;
|
||||||
|
if (token != LEASE) {
|
||||||
|
warning("Corrupt lease file - possible data loss!");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
parse_client_lease_statement(cfile, 0);
|
||||||
|
|
||||||
|
} while (1);
|
||||||
|
fclose(cfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* client-declaration :==
|
||||||
|
* SEND option-decl |
|
||||||
|
* DEFAULT option-decl |
|
||||||
|
* SUPERSEDE option-decl |
|
||||||
|
* PREPEND option-decl |
|
||||||
|
* APPEND option-decl |
|
||||||
|
* hardware-declaration |
|
||||||
|
* REQUEST option-list |
|
||||||
|
* REQUIRE option-list |
|
||||||
|
* TIMEOUT number |
|
||||||
|
* RETRY number |
|
||||||
|
* REBOOT number |
|
||||||
|
* SELECT_TIMEOUT number |
|
||||||
|
* SCRIPT string |
|
||||||
|
* interface-declaration |
|
||||||
|
* LEASE client-lease-statement |
|
||||||
|
* ALIAS client-lease-statement
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse_client_statement(FILE *cfile, struct interface_info *ip,
|
||||||
|
struct client_config *config)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
struct option *option;
|
||||||
|
|
||||||
|
switch (next_token(&val, cfile)) {
|
||||||
|
case SEND:
|
||||||
|
parse_option_decl(cfile, &config->send_options[0]);
|
||||||
|
return;
|
||||||
|
case DEFAULT:
|
||||||
|
option = parse_option_decl(cfile, &config->defaults[0]);
|
||||||
|
if (option)
|
||||||
|
config->default_actions[option->code] = ACTION_DEFAULT;
|
||||||
|
return;
|
||||||
|
case SUPERSEDE:
|
||||||
|
option = parse_option_decl(cfile, &config->defaults[0]);
|
||||||
|
if (option)
|
||||||
|
config->default_actions[option->code] =
|
||||||
|
ACTION_SUPERSEDE;
|
||||||
|
return;
|
||||||
|
case APPEND:
|
||||||
|
option = parse_option_decl(cfile, &config->defaults[0]);
|
||||||
|
if (option)
|
||||||
|
config->default_actions[option->code] = ACTION_APPEND;
|
||||||
|
return;
|
||||||
|
case PREPEND:
|
||||||
|
option = parse_option_decl(cfile, &config->defaults[0]);
|
||||||
|
if (option)
|
||||||
|
config->default_actions[option->code] = ACTION_PREPEND;
|
||||||
|
return;
|
||||||
|
case MEDIA:
|
||||||
|
parse_string_list(cfile, &config->media, 1);
|
||||||
|
return;
|
||||||
|
case HARDWARE:
|
||||||
|
if (ip)
|
||||||
|
parse_hardware_param(cfile, &ip->hw_address);
|
||||||
|
else {
|
||||||
|
parse_warn("hardware address parameter %s",
|
||||||
|
"not allowed here.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case REQUEST:
|
||||||
|
config->requested_option_count =
|
||||||
|
parse_option_list(cfile, config->requested_options);
|
||||||
|
return;
|
||||||
|
case REQUIRE:
|
||||||
|
memset(config->required_options, 0,
|
||||||
|
sizeof(config->required_options));
|
||||||
|
parse_option_list(cfile, config->required_options);
|
||||||
|
return;
|
||||||
|
case TIMEOUT:
|
||||||
|
parse_lease_time(cfile, &config->timeout);
|
||||||
|
return;
|
||||||
|
case RETRY:
|
||||||
|
parse_lease_time(cfile, &config->retry_interval);
|
||||||
|
return;
|
||||||
|
case SELECT_TIMEOUT:
|
||||||
|
parse_lease_time(cfile, &config->select_interval);
|
||||||
|
return;
|
||||||
|
case REBOOT:
|
||||||
|
parse_lease_time(cfile, &config->reboot_timeout);
|
||||||
|
return;
|
||||||
|
case BACKOFF_CUTOFF:
|
||||||
|
parse_lease_time(cfile, &config->backoff_cutoff);
|
||||||
|
return;
|
||||||
|
case INITIAL_INTERVAL:
|
||||||
|
parse_lease_time(cfile, &config->initial_interval);
|
||||||
|
return;
|
||||||
|
case SCRIPT:
|
||||||
|
config->script_name = parse_string(cfile);
|
||||||
|
return;
|
||||||
|
case INTERFACE:
|
||||||
|
if (ip)
|
||||||
|
parse_warn("nested interface declaration.");
|
||||||
|
parse_interface_declaration(cfile, config);
|
||||||
|
return;
|
||||||
|
case LEASE:
|
||||||
|
parse_client_lease_statement(cfile, 1);
|
||||||
|
return;
|
||||||
|
case ALIAS:
|
||||||
|
parse_client_lease_statement(cfile, 2);
|
||||||
|
return;
|
||||||
|
case REJECT:
|
||||||
|
parse_reject_statement(cfile, config);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
parse_warn("expecting a statement.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("semicolon expected.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parse_X(FILE *cfile, u_int8_t *buf, int max)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
token = peek_token(&val, cfile);
|
||||||
|
if (token == NUMBER_OR_NAME || token == NUMBER) {
|
||||||
|
len = 0;
|
||||||
|
do {
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER && token != NUMBER_OR_NAME) {
|
||||||
|
parse_warn("expecting hexadecimal constant.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
convert_num(&buf[len], val, 16, 8);
|
||||||
|
if (len++ > max) {
|
||||||
|
parse_warn("hexadecimal constant too long.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
token = peek_token(&val, cfile);
|
||||||
|
if (token == COLON)
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
} while (token == COLON);
|
||||||
|
val = (char *)buf;
|
||||||
|
} else if (token == STRING) {
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
len = strlen(val);
|
||||||
|
if (len + 1 > max) {
|
||||||
|
parse_warn("string constant too long.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
memcpy(buf, val, len + 1);
|
||||||
|
} else {
|
||||||
|
parse_warn("expecting string or hexadecimal data");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* option-list :== option_name |
|
||||||
|
* option_list COMMA option_name
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
parse_option_list(FILE *cfile, u_int8_t *list)
|
||||||
|
{
|
||||||
|
int ix, i;
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
ix = 0;
|
||||||
|
do {
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (!is_identifier(token)) {
|
||||||
|
parse_warn("expected option name.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
if (!strcasecmp(dhcp_options[i].name, val))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == 256) {
|
||||||
|
parse_warn("%s: unexpected option name.", val);
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
list[ix++] = i;
|
||||||
|
if (ix == 256) {
|
||||||
|
parse_warn("%s: too many options.", val);
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
} while (token == COMMA);
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("expecting semicolon.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (ix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* interface-declaration :==
|
||||||
|
* INTERFACE string LBRACE client-declarations RBRACE
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse_interface_declaration(FILE *cfile, struct client_config *outer_config)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
struct interface_info *ip;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != STRING) {
|
||||||
|
parse_warn("expecting interface name (in quotes).");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = interface_or_dummy(val);
|
||||||
|
|
||||||
|
if (!ip->client)
|
||||||
|
make_client_state(ip);
|
||||||
|
|
||||||
|
if (!ip->client->config)
|
||||||
|
make_client_config(ip, outer_config);
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != LBRACE) {
|
||||||
|
parse_warn("expecting left brace.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = peek_token(&val, cfile);
|
||||||
|
if (token == EOF) {
|
||||||
|
parse_warn("unterminated interface declaration.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (token == RBRACE)
|
||||||
|
break;
|
||||||
|
parse_client_statement(cfile, ip, ip->client->config);
|
||||||
|
} while (1);
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct interface_info *
|
||||||
|
interface_or_dummy(char *name)
|
||||||
|
{
|
||||||
|
struct interface_info *ip;
|
||||||
|
|
||||||
|
/* Find the interface (if any) that matches the name. */
|
||||||
|
if (!strcmp(ifi->name, name))
|
||||||
|
return (ifi);
|
||||||
|
|
||||||
|
/* If it's not a real interface, see if it's on the dummy list. */
|
||||||
|
for (ip = dummy_interfaces; ip; ip = ip->next)
|
||||||
|
if (!strcmp(ip->name, name))
|
||||||
|
return (ip);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we didn't find an interface, make a dummy interface as a
|
||||||
|
* placeholder.
|
||||||
|
*/
|
||||||
|
ip = malloc(sizeof(*ip));
|
||||||
|
if (!ip)
|
||||||
|
error("Insufficient memory to record interface %s", name);
|
||||||
|
memset(ip, 0, sizeof(*ip));
|
||||||
|
strlcpy(ip->name, name, IFNAMSIZ);
|
||||||
|
ip->next = dummy_interfaces;
|
||||||
|
dummy_interfaces = ip;
|
||||||
|
return (ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
make_client_state(struct interface_info *ip)
|
||||||
|
{
|
||||||
|
ip->client = malloc(sizeof(*(ip->client)));
|
||||||
|
if (!ip->client)
|
||||||
|
error("no memory for state on %s", ip->name);
|
||||||
|
memset(ip->client, 0, sizeof(*(ip->client)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
make_client_config(struct interface_info *ip, struct client_config *config)
|
||||||
|
{
|
||||||
|
ip->client->config = malloc(sizeof(struct client_config));
|
||||||
|
if (!ip->client->config)
|
||||||
|
error("no memory for config for %s", ip->name);
|
||||||
|
memset(ip->client->config, 0, sizeof(*(ip->client->config)));
|
||||||
|
memcpy(ip->client->config, config, sizeof(*config));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* client-lease-statement :==
|
||||||
|
* RBRACE client-lease-declarations LBRACE
|
||||||
|
*
|
||||||
|
* client-lease-declarations :==
|
||||||
|
* <nil> |
|
||||||
|
* client-lease-declaration |
|
||||||
|
* client-lease-declarations client-lease-declaration
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse_client_lease_statement(FILE *cfile, int is_static)
|
||||||
|
{
|
||||||
|
struct client_lease *lease, *lp, *pl;
|
||||||
|
struct interface_info *ip;
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != LBRACE) {
|
||||||
|
parse_warn("expecting left brace.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lease = malloc(sizeof(struct client_lease));
|
||||||
|
if (!lease)
|
||||||
|
error("no memory for lease.");
|
||||||
|
memset(lease, 0, sizeof(*lease));
|
||||||
|
lease->is_static = is_static;
|
||||||
|
|
||||||
|
ip = NULL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = peek_token(&val, cfile);
|
||||||
|
if (token == EOF) {
|
||||||
|
parse_warn("unterminated lease declaration.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (token == RBRACE)
|
||||||
|
break;
|
||||||
|
parse_client_lease_declaration(cfile, lease, &ip);
|
||||||
|
} while (1);
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
|
||||||
|
/* If the lease declaration didn't include an interface
|
||||||
|
* declaration that we recognized, it's of no use to us.
|
||||||
|
*/
|
||||||
|
if (!ip) {
|
||||||
|
free_client_lease(lease);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure there's a client state structure... */
|
||||||
|
if (!ip->client)
|
||||||
|
make_client_state(ip);
|
||||||
|
|
||||||
|
/* If this is an alias lease, it doesn't need to be sorted in. */
|
||||||
|
if (is_static == 2) {
|
||||||
|
ip->client->alias = lease;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The new lease may supersede a lease that's not the active
|
||||||
|
* lease but is still on the lease list, so scan the lease list
|
||||||
|
* looking for a lease with the same address, and if we find it,
|
||||||
|
* toss it.
|
||||||
|
*/
|
||||||
|
pl = NULL;
|
||||||
|
for (lp = ip->client->leases; lp; lp = lp->next) {
|
||||||
|
if (lp->address.len == lease->address.len &&
|
||||||
|
!memcmp(lp->address.iabuf, lease->address.iabuf,
|
||||||
|
lease->address.len)) {
|
||||||
|
if (pl)
|
||||||
|
pl->next = lp->next;
|
||||||
|
else
|
||||||
|
ip->client->leases = lp->next;
|
||||||
|
free_client_lease(lp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is a preloaded lease, just put it on the list of
|
||||||
|
* recorded leases - don't make it the active lease.
|
||||||
|
*/
|
||||||
|
if (is_static) {
|
||||||
|
lease->next = ip->client->leases;
|
||||||
|
ip->client->leases = lease;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The last lease in the lease file on a particular interface is
|
||||||
|
* the active lease for that interface. Of course, we don't
|
||||||
|
* know what the last lease in the file is until we've parsed
|
||||||
|
* the whole file, so at this point, we assume that the lease we
|
||||||
|
* just parsed is the active lease for its interface. If
|
||||||
|
* there's already an active lease for the interface, and this
|
||||||
|
* lease is for the same ip address, then we just toss the old
|
||||||
|
* active lease and replace it with this one. If this lease is
|
||||||
|
* for a different address, then if the old active lease has
|
||||||
|
* expired, we dump it; if not, we put it on the list of leases
|
||||||
|
* for this interface which are still valid but no longer
|
||||||
|
* active.
|
||||||
|
*/
|
||||||
|
if (ip->client->active) {
|
||||||
|
if (ip->client->active->expiry < cur_time)
|
||||||
|
free_client_lease(ip->client->active);
|
||||||
|
else if (ip->client->active->address.len ==
|
||||||
|
lease->address.len &&
|
||||||
|
!memcmp(ip->client->active->address.iabuf,
|
||||||
|
lease->address.iabuf, lease->address.len))
|
||||||
|
free_client_lease(ip->client->active);
|
||||||
|
else {
|
||||||
|
ip->client->active->next = ip->client->leases;
|
||||||
|
ip->client->leases = ip->client->active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ip->client->active = lease;
|
||||||
|
|
||||||
|
/* Phew. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* client-lease-declaration :==
|
||||||
|
* BOOTP |
|
||||||
|
* INTERFACE string |
|
||||||
|
* FIXED_ADDR ip_address |
|
||||||
|
* FILENAME string |
|
||||||
|
* SERVER_NAME string |
|
||||||
|
* OPTION option-decl |
|
||||||
|
* RENEW time-decl |
|
||||||
|
* REBIND time-decl |
|
||||||
|
* EXPIRE time-decl
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse_client_lease_declaration(FILE *cfile, struct client_lease *lease,
|
||||||
|
struct interface_info **ipp)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
struct interface_info *ip;
|
||||||
|
|
||||||
|
switch (next_token(&val, cfile)) {
|
||||||
|
case BOOTP:
|
||||||
|
lease->is_bootp = 1;
|
||||||
|
break;
|
||||||
|
case INTERFACE:
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != STRING) {
|
||||||
|
parse_warn("expecting interface name (in quotes).");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ip = interface_or_dummy(val);
|
||||||
|
*ipp = ip;
|
||||||
|
break;
|
||||||
|
case FIXED_ADDR:
|
||||||
|
if (!parse_ip_addr(cfile, &lease->address))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case MEDIUM:
|
||||||
|
parse_string_list(cfile, &lease->medium, 0);
|
||||||
|
return;
|
||||||
|
case FILENAME:
|
||||||
|
lease->filename = parse_string(cfile);
|
||||||
|
return;
|
||||||
|
case SERVER_NAME:
|
||||||
|
lease->server_name = parse_string(cfile);
|
||||||
|
return;
|
||||||
|
case RENEW:
|
||||||
|
lease->renewal = parse_date(cfile);
|
||||||
|
return;
|
||||||
|
case REBIND:
|
||||||
|
lease->rebind = parse_date(cfile);
|
||||||
|
return;
|
||||||
|
case EXPIRE:
|
||||||
|
lease->expiry = parse_date(cfile);
|
||||||
|
return;
|
||||||
|
case OPTION:
|
||||||
|
parse_option_decl(cfile, lease->options);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
parse_warn("expecting lease declaration.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("expecting semicolon.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct option *
|
||||||
|
parse_option_decl(FILE *cfile, struct option_data *options)
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
u_int8_t buf[4];
|
||||||
|
u_int8_t hunkbuf[1024];
|
||||||
|
int hunkix = 0;
|
||||||
|
char *vendor;
|
||||||
|
char *fmt;
|
||||||
|
struct universe *universe;
|
||||||
|
struct option *option;
|
||||||
|
struct iaddr ip_addr;
|
||||||
|
u_int8_t *dp;
|
||||||
|
int len;
|
||||||
|
int nul_term = 0;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (!is_identifier(token)) {
|
||||||
|
parse_warn("expecting identifier after option keyword.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if ((vendor = strdup(val)) == NULL)
|
||||||
|
error("no memory for vendor information.");
|
||||||
|
|
||||||
|
token = peek_token(&val, cfile);
|
||||||
|
if (token == DOT) {
|
||||||
|
/* Go ahead and take the DOT token... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
|
||||||
|
/* The next token should be an identifier... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (!is_identifier(token)) {
|
||||||
|
parse_warn("expecting identifier after '.'");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look up the option name hash table for the specified
|
||||||
|
vendor. */
|
||||||
|
universe = ((struct universe *)hash_lookup(&universe_hash,
|
||||||
|
(unsigned char *)vendor, 0));
|
||||||
|
/* If it's not there, we can't parse the rest of the
|
||||||
|
declaration. */
|
||||||
|
if (!universe) {
|
||||||
|
parse_warn("no vendor named %s.", vendor);
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Use the default hash table, which contains all the
|
||||||
|
standard dhcp option names. */
|
||||||
|
val = vendor;
|
||||||
|
universe = &dhcp_universe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look up the actual option info... */
|
||||||
|
option = (struct option *)hash_lookup(universe->hash,
|
||||||
|
(unsigned char *)val, 0);
|
||||||
|
|
||||||
|
/* If we didn't get an option structure, it's an undefined option. */
|
||||||
|
if (!option) {
|
||||||
|
if (val == vendor)
|
||||||
|
parse_warn("no option named %s", val);
|
||||||
|
else
|
||||||
|
parse_warn("no option named %s for vendor %s",
|
||||||
|
val, vendor);
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the initial identifier token. */
|
||||||
|
free(vendor);
|
||||||
|
|
||||||
|
/* Parse the option data... */
|
||||||
|
do {
|
||||||
|
for (fmt = option->format; *fmt; fmt++) {
|
||||||
|
if (*fmt == 'A')
|
||||||
|
break;
|
||||||
|
switch (*fmt) {
|
||||||
|
case 'X':
|
||||||
|
len = parse_X(cfile, &hunkbuf[hunkix],
|
||||||
|
sizeof(hunkbuf) - hunkix);
|
||||||
|
hunkix += len;
|
||||||
|
break;
|
||||||
|
case 't': /* Text string... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != STRING) {
|
||||||
|
parse_warn("expecting string.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
len = strlen(val);
|
||||||
|
if (hunkix + len + 1 > sizeof(hunkbuf)) {
|
||||||
|
parse_warn("option data buffer %s",
|
||||||
|
"overflow");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
memcpy(&hunkbuf[hunkix], val, len + 1);
|
||||||
|
nul_term = 1;
|
||||||
|
hunkix += len;
|
||||||
|
break;
|
||||||
|
case 'I': /* IP address. */
|
||||||
|
if (!parse_ip_addr(cfile, &ip_addr))
|
||||||
|
return (NULL);
|
||||||
|
len = ip_addr.len;
|
||||||
|
dp = ip_addr.iabuf;
|
||||||
|
alloc:
|
||||||
|
if (hunkix + len > sizeof(hunkbuf)) {
|
||||||
|
parse_warn("option data buffer "
|
||||||
|
"overflow");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
memcpy(&hunkbuf[hunkix], dp, len);
|
||||||
|
hunkix += len;
|
||||||
|
break;
|
||||||
|
case 'L': /* Unsigned 32-bit integer... */
|
||||||
|
case 'l': /* Signed 32-bit integer... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
need_number:
|
||||||
|
parse_warn("expecting number.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
convert_num(buf, val, 0, 32);
|
||||||
|
len = 4;
|
||||||
|
dp = buf;
|
||||||
|
goto alloc;
|
||||||
|
case 's': /* Signed 16-bit integer. */
|
||||||
|
case 'S': /* Unsigned 16-bit integer. */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER)
|
||||||
|
goto need_number;
|
||||||
|
convert_num(buf, val, 0, 16);
|
||||||
|
len = 2;
|
||||||
|
dp = buf;
|
||||||
|
goto alloc;
|
||||||
|
case 'b': /* Signed 8-bit integer. */
|
||||||
|
case 'B': /* Unsigned 8-bit integer. */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER)
|
||||||
|
goto need_number;
|
||||||
|
convert_num(buf, val, 0, 8);
|
||||||
|
len = 1;
|
||||||
|
dp = buf;
|
||||||
|
goto alloc;
|
||||||
|
case 'f': /* Boolean flag. */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (!is_identifier(token)) {
|
||||||
|
parse_warn("expecting identifier.");
|
||||||
|
bad_flag:
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (!strcasecmp(val, "true") ||
|
||||||
|
!strcasecmp(val, "on"))
|
||||||
|
buf[0] = 1;
|
||||||
|
else if (!strcasecmp(val, "false") ||
|
||||||
|
!strcasecmp(val, "off"))
|
||||||
|
buf[0] = 0;
|
||||||
|
else {
|
||||||
|
parse_warn("expecting boolean.");
|
||||||
|
goto bad_flag;
|
||||||
|
}
|
||||||
|
len = 1;
|
||||||
|
dp = buf;
|
||||||
|
goto alloc;
|
||||||
|
default:
|
||||||
|
warning("Bad format %c in parse_option_param.",
|
||||||
|
*fmt);
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
} while (*fmt == 'A' && token == COMMA);
|
||||||
|
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("semicolon expected.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
options[option->code].data = malloc(hunkix + nul_term);
|
||||||
|
if (!options[option->code].data)
|
||||||
|
error("out of memory allocating option data.");
|
||||||
|
memcpy(options[option->code].data, hunkbuf, hunkix + nul_term);
|
||||||
|
options[option->code].len = hunkix;
|
||||||
|
return (option);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_string_list(FILE *cfile, struct string_list **lp, int multiple)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
struct string_list *cur, *tmp;
|
||||||
|
|
||||||
|
/* Find the last medium in the media list. */
|
||||||
|
if (*lp)
|
||||||
|
for (cur = *lp; cur->next; cur = cur->next)
|
||||||
|
; /* nothing */
|
||||||
|
else
|
||||||
|
cur = NULL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != STRING) {
|
||||||
|
parse_warn("Expecting media options.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = new_string_list(strlen(val) + 1);
|
||||||
|
if (tmp == NULL)
|
||||||
|
error("no memory for string list entry.");
|
||||||
|
strlcpy(tmp->string, val, strlen(val) + 1);
|
||||||
|
tmp->next = NULL;
|
||||||
|
|
||||||
|
/* Store this medium at the end of the media list. */
|
||||||
|
if (cur)
|
||||||
|
cur->next = tmp;
|
||||||
|
else
|
||||||
|
*lp = tmp;
|
||||||
|
cur = tmp;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
} while (multiple && token == COMMA);
|
||||||
|
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("expecting semicolon.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_reject_statement(FILE *cfile, struct client_config *config)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
struct iaddr addr;
|
||||||
|
struct iaddrlist *list;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!parse_ip_addr(cfile, &addr)) {
|
||||||
|
parse_warn("expecting IP address.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = malloc(sizeof(struct iaddrlist));
|
||||||
|
if (!list)
|
||||||
|
error("no memory for reject list!");
|
||||||
|
|
||||||
|
list->addr = addr;
|
||||||
|
list->next = config->reject_list;
|
||||||
|
config->reject_list = list;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
} while (token == COMMA);
|
||||||
|
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("expecting semicolon.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
}
|
||||||
|
}
|
525
sbin/dhclient/conflex.c
Normal file
525
sbin/dhclient/conflex.c
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
/* $OpenBSD: conflex.c,v 1.7 2004/09/15 19:02:38 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Lexical scanner for dhcpd config file... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
#include "dhctoken.h"
|
||||||
|
|
||||||
|
int lexline;
|
||||||
|
int lexchar;
|
||||||
|
char *token_line;
|
||||||
|
char *prev_line;
|
||||||
|
char *cur_line;
|
||||||
|
char *tlname;
|
||||||
|
int eol_token;
|
||||||
|
|
||||||
|
static char line1[81];
|
||||||
|
static char line2[81];
|
||||||
|
static int lpos;
|
||||||
|
static int line;
|
||||||
|
static int tlpos;
|
||||||
|
static int tline;
|
||||||
|
static int token;
|
||||||
|
static int ugflag;
|
||||||
|
static char *tval;
|
||||||
|
static char tokbuf[1500];
|
||||||
|
|
||||||
|
static int get_char(FILE *);
|
||||||
|
static int get_token(FILE *);
|
||||||
|
static void skip_to_eol(FILE *);
|
||||||
|
static int read_string(FILE *);
|
||||||
|
static int read_number(int, FILE *);
|
||||||
|
static int read_num_or_name(int, FILE *);
|
||||||
|
static int intern(char *, int);
|
||||||
|
|
||||||
|
void
|
||||||
|
new_parse(char *name)
|
||||||
|
{
|
||||||
|
tlname = name;
|
||||||
|
lpos = line = 1;
|
||||||
|
cur_line = line1;
|
||||||
|
prev_line = line2;
|
||||||
|
token_line = cur_line;
|
||||||
|
cur_line[0] = prev_line[0] = 0;
|
||||||
|
warnings_occurred = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_char(FILE *cfile)
|
||||||
|
{
|
||||||
|
int c = getc(cfile);
|
||||||
|
if (!ugflag) {
|
||||||
|
if (c == '\n') {
|
||||||
|
if (cur_line == line1) {
|
||||||
|
cur_line = line2;
|
||||||
|
prev_line = line1;
|
||||||
|
} else {
|
||||||
|
cur_line = line2;
|
||||||
|
prev_line = line1;
|
||||||
|
}
|
||||||
|
line++;
|
||||||
|
lpos = 1;
|
||||||
|
cur_line[0] = 0;
|
||||||
|
} else if (c != EOF) {
|
||||||
|
if (lpos <= 81) {
|
||||||
|
cur_line[lpos - 1] = c;
|
||||||
|
cur_line[lpos] = 0;
|
||||||
|
}
|
||||||
|
lpos++;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
ugflag = 0;
|
||||||
|
return (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_token(FILE *cfile)
|
||||||
|
{
|
||||||
|
int c, ttok;
|
||||||
|
static char tb[2];
|
||||||
|
int l, p;
|
||||||
|
|
||||||
|
do {
|
||||||
|
l = line;
|
||||||
|
p = lpos;
|
||||||
|
|
||||||
|
c = get_char(cfile);
|
||||||
|
|
||||||
|
if (!(c == '\n' && eol_token) && isascii(c) && isspace(c))
|
||||||
|
continue;
|
||||||
|
if (c == '#') {
|
||||||
|
skip_to_eol(cfile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == '"') {
|
||||||
|
lexline = l;
|
||||||
|
lexchar = p;
|
||||||
|
ttok = read_string(cfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((isascii(c) && isdigit(c)) || c == '-') {
|
||||||
|
lexline = l;
|
||||||
|
lexchar = p;
|
||||||
|
ttok = read_number(c, cfile);
|
||||||
|
break;
|
||||||
|
} else if (isascii(c) && isalpha(c)) {
|
||||||
|
lexline = l;
|
||||||
|
lexchar = p;
|
||||||
|
ttok = read_num_or_name(c, cfile);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
lexline = l;
|
||||||
|
lexchar = p;
|
||||||
|
tb[0] = c;
|
||||||
|
tb[1] = 0;
|
||||||
|
tval = tb;
|
||||||
|
ttok = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
return (ttok);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
next_token(char **rval, FILE *cfile)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
if (lexline != tline)
|
||||||
|
token_line = cur_line;
|
||||||
|
lexchar = tlpos;
|
||||||
|
lexline = tline;
|
||||||
|
rv = token;
|
||||||
|
token = 0;
|
||||||
|
} else {
|
||||||
|
rv = get_token(cfile);
|
||||||
|
token_line = cur_line;
|
||||||
|
}
|
||||||
|
if (rval)
|
||||||
|
*rval = tval;
|
||||||
|
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
peek_token(char **rval, FILE *cfile)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
tlpos = lexchar;
|
||||||
|
tline = lexline;
|
||||||
|
token = get_token(cfile);
|
||||||
|
if (lexline != tline)
|
||||||
|
token_line = prev_line;
|
||||||
|
x = lexchar;
|
||||||
|
lexchar = tlpos;
|
||||||
|
tlpos = x;
|
||||||
|
x = lexline;
|
||||||
|
lexline = tline;
|
||||||
|
tline = x;
|
||||||
|
}
|
||||||
|
if (rval)
|
||||||
|
*rval = tval;
|
||||||
|
|
||||||
|
return (token);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
skip_to_eol(FILE *cfile)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c = get_char(cfile);
|
||||||
|
if (c == EOF)
|
||||||
|
return;
|
||||||
|
if (c == '\n')
|
||||||
|
return;
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_string(FILE *cfile)
|
||||||
|
{
|
||||||
|
int i, c, bs = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(tokbuf); i++) {
|
||||||
|
c = get_char(cfile);
|
||||||
|
if (c == EOF) {
|
||||||
|
parse_warn("eof in string constant");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bs) {
|
||||||
|
bs = 0;
|
||||||
|
tokbuf[i] = c;
|
||||||
|
} else if (c == '\\')
|
||||||
|
bs = 1;
|
||||||
|
else if (c == '"')
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
tokbuf[i] = c;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Normally, I'd feel guilty about this, but we're talking about
|
||||||
|
* strings that'll fit in a DHCP packet here...
|
||||||
|
*/
|
||||||
|
if (i == sizeof(tokbuf)) {
|
||||||
|
parse_warn("string constant larger than internal buffer");
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
tokbuf[i] = 0;
|
||||||
|
tval = tokbuf;
|
||||||
|
return (STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_number(int c, FILE *cfile)
|
||||||
|
{
|
||||||
|
int seenx = 0, i = 0, token = NUMBER;
|
||||||
|
|
||||||
|
tokbuf[i++] = c;
|
||||||
|
for (; i < sizeof(tokbuf); i++) {
|
||||||
|
c = get_char(cfile);
|
||||||
|
if (!seenx && c == 'x')
|
||||||
|
seenx = 1;
|
||||||
|
else if (!isascii(c) || !isxdigit(c)) {
|
||||||
|
ungetc(c, cfile);
|
||||||
|
ugflag = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tokbuf[i] = c;
|
||||||
|
}
|
||||||
|
if (i == sizeof(tokbuf)) {
|
||||||
|
parse_warn("numeric token larger than internal buffer");
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
tokbuf[i] = 0;
|
||||||
|
tval = tokbuf;
|
||||||
|
|
||||||
|
return (token);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_num_or_name(int c, FILE *cfile)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int rv = NUMBER_OR_NAME;
|
||||||
|
|
||||||
|
tokbuf[i++] = c;
|
||||||
|
for (; i < sizeof(tokbuf); i++) {
|
||||||
|
c = get_char(cfile);
|
||||||
|
if (!isascii(c) || (c != '-' && c != '_' && !isalnum(c))) {
|
||||||
|
ungetc(c, cfile);
|
||||||
|
ugflag = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isxdigit(c))
|
||||||
|
rv = NAME;
|
||||||
|
tokbuf[i] = c;
|
||||||
|
}
|
||||||
|
if (i == sizeof(tokbuf)) {
|
||||||
|
parse_warn("token larger than internal buffer");
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
tokbuf[i] = 0;
|
||||||
|
tval = tokbuf;
|
||||||
|
|
||||||
|
return (intern(tval, rv));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
intern(char *atom, int dfv)
|
||||||
|
{
|
||||||
|
if (!isascii(atom[0]))
|
||||||
|
return (dfv);
|
||||||
|
|
||||||
|
switch (tolower(atom[0])) {
|
||||||
|
case 'a':
|
||||||
|
if (!strcasecmp(atom + 1, "lways-reply-rfc1048"))
|
||||||
|
return (ALWAYS_REPLY_RFC1048);
|
||||||
|
if (!strcasecmp(atom + 1, "ppend"))
|
||||||
|
return (APPEND);
|
||||||
|
if (!strcasecmp(atom + 1, "llow"))
|
||||||
|
return (ALLOW);
|
||||||
|
if (!strcasecmp(atom + 1, "lias"))
|
||||||
|
return (ALIAS);
|
||||||
|
if (!strcasecmp(atom + 1, "bandoned"))
|
||||||
|
return (ABANDONED);
|
||||||
|
if (!strcasecmp(atom + 1, "uthoritative"))
|
||||||
|
return (AUTHORITATIVE);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
if (!strcasecmp(atom + 1, "ackoff-cutoff"))
|
||||||
|
return (BACKOFF_CUTOFF);
|
||||||
|
if (!strcasecmp(atom + 1, "ootp"))
|
||||||
|
return (BOOTP);
|
||||||
|
if (!strcasecmp(atom + 1, "ooting"))
|
||||||
|
return (BOOTING);
|
||||||
|
if (!strcasecmp(atom + 1, "oot-unknown-clients"))
|
||||||
|
return (BOOT_UNKNOWN_CLIENTS);
|
||||||
|
case 'c':
|
||||||
|
if (!strcasecmp(atom + 1, "lass"))
|
||||||
|
return (CLASS);
|
||||||
|
if (!strcasecmp(atom + 1, "iaddr"))
|
||||||
|
return (CIADDR);
|
||||||
|
if (!strcasecmp(atom + 1, "lient-identifier"))
|
||||||
|
return (CLIENT_IDENTIFIER);
|
||||||
|
if (!strcasecmp(atom + 1, "lient-hostname"))
|
||||||
|
return (CLIENT_HOSTNAME);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
if (!strcasecmp(atom + 1, "omain"))
|
||||||
|
return (DOMAIN);
|
||||||
|
if (!strcasecmp(atom + 1, "eny"))
|
||||||
|
return (DENY);
|
||||||
|
if (!strncasecmp(atom + 1, "efault", 6)) {
|
||||||
|
if (!atom[7])
|
||||||
|
return (DEFAULT);
|
||||||
|
if (!strcasecmp(atom + 7, "-lease-time"))
|
||||||
|
return (DEFAULT_LEASE_TIME);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!strncasecmp(atom + 1, "ynamic-bootp", 12)) {
|
||||||
|
if (!atom[13])
|
||||||
|
return (DYNAMIC_BOOTP);
|
||||||
|
if (!strcasecmp(atom + 13, "-lease-cutoff"))
|
||||||
|
return (DYNAMIC_BOOTP_LEASE_CUTOFF);
|
||||||
|
if (!strcasecmp(atom + 13, "-lease-length"))
|
||||||
|
return (DYNAMIC_BOOTP_LEASE_LENGTH);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
if (!strcasecmp(atom + 1, "thernet"))
|
||||||
|
return (ETHERNET);
|
||||||
|
if (!strcasecmp(atom + 1, "nds"))
|
||||||
|
return (ENDS);
|
||||||
|
if (!strcasecmp(atom + 1, "xpire"))
|
||||||
|
return (EXPIRE);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
if (!strcasecmp(atom + 1, "ilename"))
|
||||||
|
return (FILENAME);
|
||||||
|
if (!strcasecmp(atom + 1, "ixed-address"))
|
||||||
|
return (FIXED_ADDR);
|
||||||
|
if (!strcasecmp(atom + 1, "ddi"))
|
||||||
|
return (FDDI);
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
if (!strcasecmp(atom + 1, "iaddr"))
|
||||||
|
return (GIADDR);
|
||||||
|
if (!strcasecmp(atom + 1, "roup"))
|
||||||
|
return (GROUP);
|
||||||
|
if (!strcasecmp(atom + 1, "et-lease-hostnames"))
|
||||||
|
return (GET_LEASE_HOSTNAMES);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
if (!strcasecmp(atom + 1, "ost"))
|
||||||
|
return (HOST);
|
||||||
|
if (!strcasecmp(atom + 1, "ardware"))
|
||||||
|
return (HARDWARE);
|
||||||
|
if (!strcasecmp(atom + 1, "ostname"))
|
||||||
|
return (HOSTNAME);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
if (!strcasecmp(atom + 1, "nitial-interval"))
|
||||||
|
return (INITIAL_INTERVAL);
|
||||||
|
if (!strcasecmp(atom + 1, "nterface"))
|
||||||
|
return (INTERFACE);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (!strcasecmp(atom + 1, "ease"))
|
||||||
|
return (LEASE);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
if (!strcasecmp(atom + 1, "ax-lease-time"))
|
||||||
|
return (MAX_LEASE_TIME);
|
||||||
|
if (!strncasecmp(atom + 1, "edi", 3)) {
|
||||||
|
if (!strcasecmp(atom + 4, "a"))
|
||||||
|
return (MEDIA);
|
||||||
|
if (!strcasecmp(atom + 4, "um"))
|
||||||
|
return (MEDIUM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
if (!strcasecmp(atom + 1, "ameserver"))
|
||||||
|
return (NAMESERVER);
|
||||||
|
if (!strcasecmp(atom + 1, "etmask"))
|
||||||
|
return (NETMASK);
|
||||||
|
if (!strcasecmp(atom + 1, "ext-server"))
|
||||||
|
return (NEXT_SERVER);
|
||||||
|
if (!strcasecmp(atom + 1, "ot"))
|
||||||
|
return (TOKEN_NOT);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
if (!strcasecmp(atom + 1, "ption"))
|
||||||
|
return (OPTION);
|
||||||
|
if (!strcasecmp(atom + 1, "ne-lease-per-client"))
|
||||||
|
return (ONE_LEASE_PER_CLIENT);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
if (!strcasecmp(atom + 1, "repend"))
|
||||||
|
return (PREPEND);
|
||||||
|
if (!strcasecmp(atom + 1, "acket"))
|
||||||
|
return (PACKET);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
if (!strcasecmp(atom + 1, "ange"))
|
||||||
|
return (RANGE);
|
||||||
|
if (!strcasecmp(atom + 1, "equest"))
|
||||||
|
return (REQUEST);
|
||||||
|
if (!strcasecmp(atom + 1, "equire"))
|
||||||
|
return (REQUIRE);
|
||||||
|
if (!strcasecmp(atom + 1, "etry"))
|
||||||
|
return (RETRY);
|
||||||
|
if (!strcasecmp(atom + 1, "enew"))
|
||||||
|
return (RENEW);
|
||||||
|
if (!strcasecmp(atom + 1, "ebind"))
|
||||||
|
return (REBIND);
|
||||||
|
if (!strcasecmp(atom + 1, "eboot"))
|
||||||
|
return (REBOOT);
|
||||||
|
if (!strcasecmp(atom + 1, "eject"))
|
||||||
|
return (REJECT);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
if (!strcasecmp(atom + 1, "earch"))
|
||||||
|
return (SEARCH);
|
||||||
|
if (!strcasecmp(atom + 1, "tarts"))
|
||||||
|
return (STARTS);
|
||||||
|
if (!strcasecmp(atom + 1, "iaddr"))
|
||||||
|
return (SIADDR);
|
||||||
|
if (!strcasecmp(atom + 1, "ubnet"))
|
||||||
|
return (SUBNET);
|
||||||
|
if (!strcasecmp(atom + 1, "hared-network"))
|
||||||
|
return (SHARED_NETWORK);
|
||||||
|
if (!strcasecmp(atom + 1, "erver-name"))
|
||||||
|
return (SERVER_NAME);
|
||||||
|
if (!strcasecmp(atom + 1, "erver-identifier"))
|
||||||
|
return (SERVER_IDENTIFIER);
|
||||||
|
if (!strcasecmp(atom + 1, "elect-timeout"))
|
||||||
|
return (SELECT_TIMEOUT);
|
||||||
|
if (!strcasecmp(atom + 1, "end"))
|
||||||
|
return (SEND);
|
||||||
|
if (!strcasecmp(atom + 1, "cript"))
|
||||||
|
return (SCRIPT);
|
||||||
|
if (!strcasecmp(atom + 1, "upersede"))
|
||||||
|
return (SUPERSEDE);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
if (!strcasecmp(atom + 1, "imestamp"))
|
||||||
|
return (TIMESTAMP);
|
||||||
|
if (!strcasecmp(atom + 1, "imeout"))
|
||||||
|
return (TIMEOUT);
|
||||||
|
if (!strcasecmp(atom + 1, "oken-ring"))
|
||||||
|
return (TOKEN_RING);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
if (!strncasecmp(atom + 1, "se", 2)) {
|
||||||
|
if (!strcasecmp(atom + 3, "r-class"))
|
||||||
|
return (USER_CLASS);
|
||||||
|
if (!strcasecmp(atom + 3, "-host-decl-names"))
|
||||||
|
return (USE_HOST_DECL_NAMES);
|
||||||
|
if (!strcasecmp(atom + 3,
|
||||||
|
"-lease-addr-for-default-route"))
|
||||||
|
return (USE_LEASE_ADDR_FOR_DEFAULT_ROUTE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(atom + 1, "id"))
|
||||||
|
return (UID);
|
||||||
|
if (!strcasecmp(atom + 1, "nknown-clients"))
|
||||||
|
return (UNKNOWN_CLIENTS);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
if (!strcasecmp(atom + 1, "endor-class"))
|
||||||
|
return (VENDOR_CLASS);
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
if (!strcasecmp(atom + 1, "iaddr"))
|
||||||
|
return (YIADDR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (dfv);
|
||||||
|
}
|
114
sbin/dhclient/convert.c
Normal file
114
sbin/dhclient/convert.c
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/* $OpenBSD: convert.c,v 1.5 2004/02/07 11:35:59 henning Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Safe copying of option values into and out of the option buffer,
|
||||||
|
* which can't be assumed to be aligned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
u_int32_t
|
||||||
|
getULong(unsigned char *buf)
|
||||||
|
{
|
||||||
|
u_int32_t ibuf;
|
||||||
|
|
||||||
|
memcpy(&ibuf, buf, sizeof(ibuf));
|
||||||
|
return (ntohl(ibuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t
|
||||||
|
getLong(unsigned char *(buf))
|
||||||
|
{
|
||||||
|
int32_t ibuf;
|
||||||
|
|
||||||
|
memcpy(&ibuf, buf, sizeof(ibuf));
|
||||||
|
return (ntohl(ibuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int16_t
|
||||||
|
getUShort(unsigned char *buf)
|
||||||
|
{
|
||||||
|
u_int16_t ibuf;
|
||||||
|
|
||||||
|
memcpy(&ibuf, buf, sizeof(ibuf));
|
||||||
|
return (ntohs(ibuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t
|
||||||
|
getShort(unsigned char *buf)
|
||||||
|
{
|
||||||
|
int16_t ibuf;
|
||||||
|
|
||||||
|
memcpy(&ibuf, buf, sizeof(ibuf));
|
||||||
|
return (ntohs(ibuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putULong(unsigned char *obuf, u_int32_t val)
|
||||||
|
{
|
||||||
|
u_int32_t tmp = htonl(val);
|
||||||
|
|
||||||
|
memcpy(obuf, &tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putLong(unsigned char *obuf, int32_t val)
|
||||||
|
{
|
||||||
|
int32_t tmp = htonl(val);
|
||||||
|
|
||||||
|
memcpy(obuf, &tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putUShort(unsigned char *obuf, unsigned int val)
|
||||||
|
{
|
||||||
|
u_int16_t tmp = htons(val);
|
||||||
|
|
||||||
|
memcpy(obuf, &tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putShort(unsigned char *obuf, int val)
|
||||||
|
{
|
||||||
|
int16_t tmp = htons(val);
|
||||||
|
|
||||||
|
memcpy(obuf, &tmp, sizeof(tmp));
|
||||||
|
}
|
227
sbin/dhclient/dhclient-script
Normal file
227
sbin/dhclient/dhclient-script
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# $OpenBSD: dhclient-script,v 1.6 2004/05/06 18:22:41 claudio Exp $
|
||||||
|
#
|
||||||
|
# Copyright (c) 2003 Kenneth R Westerback <krw@openbsd.org>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Helper functions that implement common actions.
|
||||||
|
#
|
||||||
|
|
||||||
|
delete_old_address() {
|
||||||
|
if [ -n "$old_ip_address" ]; then
|
||||||
|
ifconfig $interface inet -alias $old_ip_address $medium
|
||||||
|
route delete "$old_ip_address" 127.0.0.1 >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
add_new_address() {
|
||||||
|
ifconfig $interface \
|
||||||
|
inet $new_ip_address \
|
||||||
|
netmask $new_subnet_mask \
|
||||||
|
broadcast $new_broadcast_address \
|
||||||
|
$medium
|
||||||
|
|
||||||
|
# XXX Original TIMEOUT code did not do this unless $new_routers was set?
|
||||||
|
route add $new_ip_address 127.0.0.1 >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_old_alias() {
|
||||||
|
if [ -n "$alias_ip_address" ]; then
|
||||||
|
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
|
||||||
|
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
add_new_alias() {
|
||||||
|
if [ -n "$alias_ip_address" ]; then
|
||||||
|
ifconfig $interface inet alias $alias_ip_address netmask \
|
||||||
|
$alias_subnet_mask
|
||||||
|
route add $alias_ip_address 127.0.0.1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_old_routes() {
|
||||||
|
# Delete existing default route. We only allow one, so no need to
|
||||||
|
# process $old_routers list.
|
||||||
|
route delete default >/dev/null 2>&1
|
||||||
|
|
||||||
|
if [ -n "$old_static_routes" ]; then
|
||||||
|
set $old_static_routes
|
||||||
|
while [ $# -gt 1 ]; do
|
||||||
|
route delete "$1" "$2"
|
||||||
|
shift; shift
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
arp -dan
|
||||||
|
}
|
||||||
|
|
||||||
|
add_new_routes() {
|
||||||
|
route delete default >/dev/null 2>&1
|
||||||
|
for router in $new_routers; do
|
||||||
|
if [ "$new_ip_address" = "$router" ]; then
|
||||||
|
route add default -iface $router >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
route add default $router >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
# 2nd and subsequent default routers error out, so explicitly
|
||||||
|
# stop processing the list after the first one.
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$new_static_routes" ]; then
|
||||||
|
set $new_static_routes
|
||||||
|
while [ $# -gt 1 ]; do
|
||||||
|
route add $1 $2
|
||||||
|
shift; shift
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
add_new_resolv_conf() {
|
||||||
|
# XXX Old code did not create/update resolv.conf unless both
|
||||||
|
# $new_domain_name and $new_domain_name_servers were provided. PR
|
||||||
|
# #3135 reported some ISP's only provide $new_domain_name_servers and
|
||||||
|
# thus broke the script. This code creates the resolv.conf if either
|
||||||
|
# are provided.
|
||||||
|
|
||||||
|
rm -f /etc/resolv.conf.std
|
||||||
|
|
||||||
|
if [ -n "$new_domain_name" ]; then
|
||||||
|
echo "search $new_domain_name" >>/etc/resolv.conf.std
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$new_domain_name_servers" ]; then
|
||||||
|
for nameserver in $new_domain_name_servers; do
|
||||||
|
echo "nameserver $nameserver" >>/etc/resolv.conf.std
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f /etc/resolv.conf.std ]; then
|
||||||
|
if [ -f /etc/resolv.conf.tail ]; then
|
||||||
|
cat /etc/resolv.conf.tail >>/etc/resolv.conf.std
|
||||||
|
fi
|
||||||
|
|
||||||
|
# In case (e.g. during OpenBSD installs) /etc/resolv.conf
|
||||||
|
# is a symbolic link, take care to preserve the link and write
|
||||||
|
# the new data in the correct location.
|
||||||
|
|
||||||
|
if [ -f /etc/resolv.conf ]; then
|
||||||
|
cat /etc/resolv.conf > /etc/resolv.conf.save
|
||||||
|
fi
|
||||||
|
cat /etc/resolv.conf.std > /etc/resolv.conf
|
||||||
|
rm -f /etc/resolv.conf.std
|
||||||
|
|
||||||
|
# Try to ensure correct ownership and permissions.
|
||||||
|
chown -RL root:wheel /etc/resolv.conf
|
||||||
|
chmod -RL 644 /etc/resolv.conf
|
||||||
|
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Start of active code.
|
||||||
|
#
|
||||||
|
|
||||||
|
if [ -n "$new_network_number" ]; then
|
||||||
|
echo "New Network Number: $new_network_number"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$new_broadcast_address" ]; then
|
||||||
|
echo "New Broadcast Address: $new_broadcast_address"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $reason in
|
||||||
|
MEDIUM)
|
||||||
|
ifconfig $interface $medium
|
||||||
|
ifconfig $interface inet -alias 0.0.0.0 $medium >/dev/null 2>&1
|
||||||
|
sleep 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
PREINIT)
|
||||||
|
delete_old_alias
|
||||||
|
ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 broadcast 255.255.255.255 up
|
||||||
|
;;
|
||||||
|
|
||||||
|
ARPCHECK|ARPSEND)
|
||||||
|
;;
|
||||||
|
|
||||||
|
BOUND|RENEW|REBIND|REBOOT)
|
||||||
|
if [ -n "$old_ip_address" ]; then
|
||||||
|
if [ "$old_ip_address" != "$alias_ip_address" ]; then
|
||||||
|
delete_old_alias
|
||||||
|
fi
|
||||||
|
if [ "$old_ip_address" != "$new_ip_address" ]; then
|
||||||
|
delete_old_address
|
||||||
|
delete_old_routes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$reason" = BOUND ] || \
|
||||||
|
[ "$reason" = REBOOT ] || \
|
||||||
|
[ -z "$old_ip_address" ] || \
|
||||||
|
[ "$old_ip_address" != "$new_ip_address" ]; then
|
||||||
|
add_new_address
|
||||||
|
add_new_routes
|
||||||
|
fi
|
||||||
|
if [ "$new_ip_address" != "$alias_ip_address" ]; then
|
||||||
|
add_new_alias
|
||||||
|
fi
|
||||||
|
add_new_resolv_conf
|
||||||
|
;;
|
||||||
|
|
||||||
|
EXPIRE|FAIL)
|
||||||
|
delete_old_alias
|
||||||
|
if [ -n "$old_ip_address" ]; then
|
||||||
|
delete_old_address
|
||||||
|
delete_old_routes
|
||||||
|
fi
|
||||||
|
# XXX Why add alias we just deleted above?
|
||||||
|
add_new_alias
|
||||||
|
if [ -f /etc/resolv.conf.save ]; then
|
||||||
|
cat /etc/resolv.conf.save > /etc/resolv.conf
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
TIMEOUT)
|
||||||
|
delete_old_alias
|
||||||
|
add_new_address
|
||||||
|
sleep 1
|
||||||
|
if [ -n "$new_routers" ]; then
|
||||||
|
set "$new_routers"
|
||||||
|
if ping -q -c 1 -w 1 "$1"; then
|
||||||
|
if [ "$new_ip_address" != "$alias_ip_address" ]; then
|
||||||
|
add_new_alias
|
||||||
|
fi
|
||||||
|
add_new_routes
|
||||||
|
if add_new_resolv_conf; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
ifconfig $interface inet -alias $new_ip_address $medium
|
||||||
|
# XXX Why not a delete_old_address as before all other invocations of
|
||||||
|
# delete_old_routes?
|
||||||
|
delete_old_routes
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
246
sbin/dhclient/dhclient-script.8
Normal file
246
sbin/dhclient/dhclient-script.8
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
.\" $OpenBSD: dhclient-script.8,v 1.2 2004/04/09 18:30:15 jmc Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1997 The Internet Software Consortium.
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\"
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" This software has been written for the Internet Software Consortium
|
||||||
|
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
.\" Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
|
||||||
|
.\" Enterprises, see ``http://www.vix.com''.
|
||||||
|
.\"
|
||||||
|
.Dd January 1, 1997
|
||||||
|
.Dt DHCLIENT-SCRIPT 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dhclient-script
|
||||||
|
.Nd DHCP client network configuration script
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The DHCP client network configuration script is invoked from time to
|
||||||
|
time by
|
||||||
|
.Xr dhclient 8 .
|
||||||
|
This script is used by the DHCP client to set each interface's initial
|
||||||
|
configuration prior to requesting an address, to test the address once it
|
||||||
|
has been offered, and to set the interface's final configuration once a
|
||||||
|
lease has been acquired.
|
||||||
|
If no lease is acquired, the script is used to test predefined leases, if
|
||||||
|
any, and also called once if no valid lease can be identified.
|
||||||
|
.Pp
|
||||||
|
.\" No standard client script exists for some operating systems, even though
|
||||||
|
.\" the actual client may work, so a pioneering user may well need to create
|
||||||
|
.\" a new script or modify an existing one.
|
||||||
|
In general, customizations specific to a particular computer should be done
|
||||||
|
in the
|
||||||
|
.Pa /etc/dhclient.conf
|
||||||
|
file.
|
||||||
|
.Sh OPERATION
|
||||||
|
When
|
||||||
|
.Xr dhclient 8
|
||||||
|
needs to invoke the client configuration script, it sets up a number of
|
||||||
|
environment variables and runs
|
||||||
|
.Nm dhclient-script .
|
||||||
|
In all cases,
|
||||||
|
.Va $reason
|
||||||
|
is set to the name of the reason why the script has been invoked.
|
||||||
|
The following reasons are currently defined:
|
||||||
|
MEDIUM, PREINIT, ARPCHECK, ARPSEND, BOUND, RENEW, REBIND, REBOOT,
|
||||||
|
EXPIRE, FAIL and TIMEOUT.
|
||||||
|
.Bl -tag -width "ARPCHECK"
|
||||||
|
.It MEDIUM
|
||||||
|
The DHCP client is requesting that an interface's media type be set.
|
||||||
|
The interface name is passed in
|
||||||
|
.Va $interface ,
|
||||||
|
and the media type is passed in
|
||||||
|
.Va $medium .
|
||||||
|
.It PREINIT
|
||||||
|
The DHCP client is requesting that an interface be configured as
|
||||||
|
required in order to send packets prior to receiving an actual address.
|
||||||
|
.\" For clients which use the BSD socket library,
|
||||||
|
This means configuring the interface with an IP address of 0.0.0.0
|
||||||
|
and a broadcast address of 255.255.255.255.
|
||||||
|
.\" For other clients, it may be possible to simply configure the interface up
|
||||||
|
.\" without actually giving it an IP address at all.
|
||||||
|
The interface name is passed in
|
||||||
|
.Va $interface ,
|
||||||
|
and the media type in
|
||||||
|
.Va $medium .
|
||||||
|
.Pp
|
||||||
|
If an IP alias has been declared in
|
||||||
|
.Xr dhclient.conf 5 ,
|
||||||
|
its address will be passed in
|
||||||
|
.Va $alias_ip_address ,
|
||||||
|
and that IP alias should be deleted from the interface,
|
||||||
|
along with any routes to it.
|
||||||
|
.It ARPSEND
|
||||||
|
The DHCP client is requesting that an address that has been offered to
|
||||||
|
it be checked to see if somebody else is using it, by sending an ARP
|
||||||
|
request for that address.
|
||||||
|
It's not clear how to implement this, so no examples exist yet.
|
||||||
|
The IP address to check is passed in
|
||||||
|
.Va $new_ip_address ,
|
||||||
|
and the interface name is passed in
|
||||||
|
.Va $interface .
|
||||||
|
.It ARPCHECK
|
||||||
|
The DHCP client wants to know if a response to the ARP request sent
|
||||||
|
using ARPSEND has been received.
|
||||||
|
If one has, the script should exit with a nonzero status, indicating that
|
||||||
|
the offered address has already been requested and should be declined.
|
||||||
|
.Va $new_ip_address
|
||||||
|
and
|
||||||
|
.Va $interface
|
||||||
|
are set as with ARPSEND.
|
||||||
|
.It BOUND
|
||||||
|
The DHCP client has done an initial binding to a new address.
|
||||||
|
The new IP address is passed in
|
||||||
|
.Va $new_ip_address ,
|
||||||
|
and the interface name is passed in
|
||||||
|
.Va $interface .
|
||||||
|
The media type is passed in
|
||||||
|
.Va $medium .
|
||||||
|
Any options acquired from the server are passed using the option name
|
||||||
|
described in
|
||||||
|
.Xr dhcp-options 5 ,
|
||||||
|
except that dashes
|
||||||
|
.Pq Sq -
|
||||||
|
are replaced by underscores
|
||||||
|
.Pq Sq _
|
||||||
|
in order to make valid shell variables, and the variable names start with new_.
|
||||||
|
So for example, the new subnet mask would be passed in
|
||||||
|
.Va $new_subnet_mask .
|
||||||
|
.Pp
|
||||||
|
When a binding has been completed, a lot of network parameters are
|
||||||
|
likely to need to be set up.
|
||||||
|
A new
|
||||||
|
.Pa /etc/resolv.conf
|
||||||
|
needs to be created, using the values of
|
||||||
|
.Va $new_domain_name
|
||||||
|
and
|
||||||
|
.Va $new_domain_name_servers
|
||||||
|
(which may list more than one server, separated by spaces).
|
||||||
|
A default route should be set using
|
||||||
|
.Va $new_routers ,
|
||||||
|
and static routes may need to be set up using
|
||||||
|
.Va $new_static_routes .
|
||||||
|
.Pp
|
||||||
|
If an IP alias has been declared, it must be set up here.
|
||||||
|
The alias IP address will be written as
|
||||||
|
.Va $alias_ip_address ,
|
||||||
|
and other DHCP options that are set for the alias (e.g., subnet mask)
|
||||||
|
will be passed in variables named as described previously except starting with
|
||||||
|
$alias_ instead of $new_.
|
||||||
|
Care should be taken that the alias IP address not be used if it is identical
|
||||||
|
to the bound IP address
|
||||||
|
.Pq Va $new_ip_address ,
|
||||||
|
since the other alias parameters may be incorrect in this case.
|
||||||
|
.It RENEW
|
||||||
|
When a binding has been renewed, the script is called as in BOUND,
|
||||||
|
except that in addition to all the variables starting with $new_,
|
||||||
|
there is another set of variables starting with $old_.
|
||||||
|
Persistent settings that may have changed need to be deleted \- for example,
|
||||||
|
if a local route to the bound address is being configured, the old local
|
||||||
|
route should be deleted.
|
||||||
|
If the default route has changed, the old default route should be deleted.
|
||||||
|
If the static routes have changed, the old ones should be deleted.
|
||||||
|
Otherwise, processing can be done as with BOUND.
|
||||||
|
.It REBIND
|
||||||
|
The DHCP client has rebound to a new DHCP server.
|
||||||
|
This can be handled as with RENEW, except that if the IP address has changed,
|
||||||
|
the ARP table should be cleared.
|
||||||
|
.It REBOOT
|
||||||
|
The DHCP client has successfully reacquired its old address after a reboot.
|
||||||
|
This can be processed as with BOUND.
|
||||||
|
.It EXPIRE
|
||||||
|
The DHCP client has failed to renew its lease or acquire a new one,
|
||||||
|
and the lease has expired.
|
||||||
|
The IP address must be relinquished, and all related parameters should be
|
||||||
|
deleted, as in RENEW and REBIND.
|
||||||
|
.It FAIL
|
||||||
|
The DHCP client has been unable to contact any DHCP servers, and any
|
||||||
|
leases that have been tested have not proved to be valid.
|
||||||
|
The parameters from the last lease tested should be deconfigured.
|
||||||
|
This can be handled in the same way as EXPIRE.
|
||||||
|
.It TIMEOUT
|
||||||
|
The DHCP client has been unable to contact any DHCP servers.
|
||||||
|
However, an old lease has been identified, and its parameters have
|
||||||
|
been passed in as with BOUND.
|
||||||
|
The client configuration script should test these parameters and,
|
||||||
|
if it has reason to believe they are valid, should exit with a value of zero.
|
||||||
|
If not, it should exit with a nonzero value.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The usual way to test a lease is to set up the network as with REBIND
|
||||||
|
(since this may be called to test more than one lease) and then ping
|
||||||
|
the first router defined in
|
||||||
|
.Va $routers .
|
||||||
|
If a response is received, the lease must be valid for the network to
|
||||||
|
which the interface is currently connected.
|
||||||
|
It would be more complete to try to ping all of the routers listed in
|
||||||
|
.Va $new_routers ,
|
||||||
|
as well as those listed in
|
||||||
|
.Va $new_static_routes ,
|
||||||
|
but current scripts do not do this.
|
||||||
|
.\" .Sh FILES
|
||||||
|
.\" Each operating system should generally have its own script file,
|
||||||
|
.\" although the script files for similar operating systems may be similar
|
||||||
|
.\" or even identical.
|
||||||
|
.\" The script files included in the Internet Software Consortium DHCP
|
||||||
|
.\" distribution appear in the distribution tree under client/scripts,
|
||||||
|
.\" and bear the names of the operating systems on which they are intended
|
||||||
|
.\" to work.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr dhclient.conf 5 ,
|
||||||
|
.Xr dhclient.leases 5 ,
|
||||||
|
.Xr dhclient 8 ,
|
||||||
|
.Xr dhcpd 8 ,
|
||||||
|
.Xr dhcrelay 8
|
||||||
|
.Sh AUTHORS
|
||||||
|
The original version of
|
||||||
|
.Nm
|
||||||
|
was written for the Internet Software Consortium by
|
||||||
|
.An Ted Lemon Aq mellon@fugue.com
|
||||||
|
in cooperation with Vixie Enterprises.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ox
|
||||||
|
implementation of
|
||||||
|
.Nm
|
||||||
|
was written by
|
||||||
|
.An Kenneth R. Westerback Aq krw@openbsd.org .
|
||||||
|
.Sh BUGS
|
||||||
|
If more than one interface is being used, there's no obvious way to
|
||||||
|
avoid clashes between server-supplied configuration parameters \- for
|
||||||
|
example, the stock dhclient-script rewrites
|
||||||
|
.Pa /etc/resolv.conf .
|
||||||
|
If more than one interface is being configured,
|
||||||
|
.Pa /etc/resolv.conf
|
||||||
|
will be repeatedly initialized to the values provided by one server, and then
|
||||||
|
the other.
|
||||||
|
Assuming the information provided by both servers is valid, this shouldn't
|
||||||
|
cause any real problems, but it could be confusing.
|
181
sbin/dhclient/dhclient.8
Normal file
181
sbin/dhclient/dhclient.8
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
.\" $OpenBSD: dhclient.8,v 1.3 2004/04/09 18:30:15 jmc Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1997 The Internet Software Consortium.
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\"
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" This software has been written for the Internet Software Consortium
|
||||||
|
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
.\" Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
|
||||||
|
.\" Enterprises, see ``http://www.vix.com''.
|
||||||
|
.Dd April 7, 2004
|
||||||
|
.Dt DHCLIENT 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dhclient
|
||||||
|
.Nd Dynamic Host Configuration Protocol (DHCP) Client
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl dqu
|
||||||
|
.Op Fl c Ar file
|
||||||
|
.Op Fl l Ar file
|
||||||
|
.Ar interface
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility provides a means for configuring network interfaces using DHCP, BOOTP,
|
||||||
|
or if these protocols fail, by statically assigning an address.
|
||||||
|
.Pp
|
||||||
|
The name of the network interface that
|
||||||
|
.Nm
|
||||||
|
should attempt to
|
||||||
|
configure must be specified on the command line.
|
||||||
|
.Pp
|
||||||
|
The options are as follows:
|
||||||
|
.Bl -tag -width "-p port"
|
||||||
|
.It Fl c Ar file
|
||||||
|
Specify an alternate location,
|
||||||
|
.Ar file ,
|
||||||
|
for the configuration file.
|
||||||
|
.It Fl d
|
||||||
|
Forces
|
||||||
|
.Nm
|
||||||
|
to always run as a foreground process.
|
||||||
|
By default,
|
||||||
|
.Nm
|
||||||
|
runs in the foreground until it has configured the interface, and then
|
||||||
|
will revert to running in the background.
|
||||||
|
.It Fl l Ar file
|
||||||
|
Specify an alternate location,
|
||||||
|
.Ar file ,
|
||||||
|
for the leases file.
|
||||||
|
.It Fl q
|
||||||
|
Forces
|
||||||
|
.Nm
|
||||||
|
to be less verbose on startup.
|
||||||
|
.It Fl u
|
||||||
|
Forces
|
||||||
|
.Nm
|
||||||
|
to reject leases with unknown options in them.
|
||||||
|
The default behaviour is to accept such lease offers.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The DHCP protocol allows a host to contact a central server which
|
||||||
|
maintains a list of IP addresses which may be assigned on one or more
|
||||||
|
subnets.
|
||||||
|
A DHCP client may request an address from this pool, and
|
||||||
|
then use it on a temporary basis for communication on the network.
|
||||||
|
The DHCP protocol also provides a mechanism whereby a client can learn
|
||||||
|
important details about the network to which it is attached, such as
|
||||||
|
the location of a default router, the location of a name server, and
|
||||||
|
so on.
|
||||||
|
.Pp
|
||||||
|
On startup,
|
||||||
|
.Nm
|
||||||
|
reads
|
||||||
|
.Pa /etc/dhclient.conf
|
||||||
|
for configuration instructions.
|
||||||
|
It then gets a list of all the
|
||||||
|
network interfaces that are configured in the current system.
|
||||||
|
It then attempts to configure each interface with DHCP.
|
||||||
|
.Pp
|
||||||
|
In order to keep track of leases across system reboots and server
|
||||||
|
restarts,
|
||||||
|
.Nm
|
||||||
|
keeps a list of leases it has been assigned in the
|
||||||
|
.Pa /var/db/dhclient.leases.IFNAME
|
||||||
|
file.
|
||||||
|
.Qq IFNAME
|
||||||
|
represents the network interface of the DHCP client
|
||||||
|
.Pq e.g. em0 ,
|
||||||
|
one for each interface.
|
||||||
|
On startup, after reading the
|
||||||
|
.Xr dhclient.conf 5
|
||||||
|
file,
|
||||||
|
.Nm
|
||||||
|
reads the leases file to refresh its memory about what leases it has been
|
||||||
|
assigned.
|
||||||
|
.Pp
|
||||||
|
Old leases are kept around in case the DHCP server is unavailable when
|
||||||
|
.Nm
|
||||||
|
is first invoked (generally during the initial system boot
|
||||||
|
process).
|
||||||
|
In that event, old leases from the
|
||||||
|
.Pa dhclient.leases.IFNAME
|
||||||
|
file which have not yet expired are tested, and if they are determined to
|
||||||
|
be valid, they are used until either they expire or the DHCP server
|
||||||
|
becomes available.
|
||||||
|
.Pp
|
||||||
|
A mobile host which may sometimes need to access a network on which no
|
||||||
|
DHCP server exists may be preloaded with a lease for a fixed
|
||||||
|
address on that network.
|
||||||
|
When all attempts to contact a DHCP server have failed,
|
||||||
|
.Nm
|
||||||
|
will try to validate the static lease, and if it
|
||||||
|
succeeds, it will use that lease until it is restarted.
|
||||||
|
.Pp
|
||||||
|
A mobile host may also travel to some networks on which DHCP is not
|
||||||
|
available but BOOTP is.
|
||||||
|
In that case, it may be advantageous to
|
||||||
|
arrange with the network administrator for an entry on the BOOTP
|
||||||
|
database, so that the host can boot quickly on that network rather
|
||||||
|
than cycling through the list of old leases.
|
||||||
|
.Sh NOTES
|
||||||
|
You must have the Berkeley Packet Filter (BPF) configured in your kernel.
|
||||||
|
.Nm
|
||||||
|
requires at least one
|
||||||
|
.Pa /dev/bpf*
|
||||||
|
file for each broadcast network interface that is attached to your system.
|
||||||
|
See
|
||||||
|
.Xr bpf 4
|
||||||
|
for more information.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /var/db/dhclient.leases.IFNAME~ -compact
|
||||||
|
.It Pa /etc/dhclient.conf
|
||||||
|
DHCP client configuration file
|
||||||
|
.It Pa /var/db/dhclient.leases.IFNAME
|
||||||
|
database of acquired leases
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr dhclient.conf 5 ,
|
||||||
|
.Xr dhclient.leases 5 ,
|
||||||
|
.Xr dhclient-script 8 ,
|
||||||
|
.Xr dhcp 8 ,
|
||||||
|
.Xr dhcpd 8 ,
|
||||||
|
.Xr dhcrelay 8
|
||||||
|
.Sh AUTHORS
|
||||||
|
.Nm
|
||||||
|
was written by
|
||||||
|
.An Ted Lemon Aq mellon@fugue.com
|
||||||
|
and
|
||||||
|
.An Elliot Poger Aq elliot@poger.com .
|
||||||
|
.Pp
|
||||||
|
The current implementation was reworked by
|
||||||
|
.An Henning Brauer Aq henning@openbsd.org .
|
2373
sbin/dhclient/dhclient.c
Normal file
2373
sbin/dhclient/dhclient.c
Normal file
File diff suppressed because it is too large
Load Diff
36
sbin/dhclient/dhclient.conf
Normal file
36
sbin/dhclient/dhclient.conf
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
send host-name "andare.fugue.com";
|
||||||
|
send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
|
||||||
|
send dhcp-lease-time 3600;
|
||||||
|
supersede domain-name "fugue.com home.vix.com";
|
||||||
|
prepend domain-name-servers 127.0.0.1;
|
||||||
|
request subnet-mask, broadcast-address, time-offset, routers,
|
||||||
|
domain-name, domain-name-servers, host-name;
|
||||||
|
require subnet-mask, domain-name-servers;
|
||||||
|
timeout 60;
|
||||||
|
retry 60;
|
||||||
|
reboot 10;
|
||||||
|
select-timeout 5;
|
||||||
|
initial-interval 2;
|
||||||
|
script "/etc/dhclient-script";
|
||||||
|
media "-link0 -link1 -link2", "link0 link1";
|
||||||
|
reject 192.33.137.209;
|
||||||
|
|
||||||
|
alias {
|
||||||
|
interface "ep0";
|
||||||
|
fixed-address 192.5.5.213;
|
||||||
|
option subnet-mask 255.255.255.255;
|
||||||
|
}
|
||||||
|
|
||||||
|
lease {
|
||||||
|
interface "ep0";
|
||||||
|
fixed-address 192.33.137.200;
|
||||||
|
medium "link0 link1";
|
||||||
|
option host-name "andare.swiftmedia.com";
|
||||||
|
option subnet-mask 255.255.255.0;
|
||||||
|
option broadcast-address 192.33.137.255;
|
||||||
|
option routers 192.33.137.250;
|
||||||
|
option domain-name-servers 127.0.0.1;
|
||||||
|
renew 2 2000/1/12 00:00:01;
|
||||||
|
rebind 2 2000/1/12 00:00:01;
|
||||||
|
expire 2 2000/1/12 00:00:01;
|
||||||
|
}
|
541
sbin/dhclient/dhclient.conf.5
Normal file
541
sbin/dhclient/dhclient.conf.5
Normal file
@ -0,0 +1,541 @@
|
|||||||
|
.\" $OpenBSD: dhclient.conf.5,v 1.5 2004/11/01 23:10:18 henning Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1997 The Internet Software Consortium.
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\"
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" This software has been written for the Internet Software Consortium
|
||||||
|
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
.\" Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
|
||||||
|
.\" Enterprises, see ``http://www.vix.com''.
|
||||||
|
.\"
|
||||||
|
.Dd January 1, 1997
|
||||||
|
.Dt DHCLIENT.CONF 5
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dhclient.conf
|
||||||
|
.Nd DHCP client configuration file
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
file contains configuration information for
|
||||||
|
.Xr dhclient 8 ,
|
||||||
|
the Internet Software Consortium DHCP Client.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
file is a free-form ASCII text file.
|
||||||
|
It is parsed by the recursive-descent parser built into
|
||||||
|
.Xr dhclient 8 .
|
||||||
|
The file may contain extra tabs and newlines for formatting purposes.
|
||||||
|
Keywords in the file are case-insensitive.
|
||||||
|
Comments may be placed anywhere within the file (except within quotes).
|
||||||
|
Comments begin with the
|
||||||
|
.Sq #
|
||||||
|
character and end at the end of the line.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
file can be used to configure the behaviour of the client in a wide variety
|
||||||
|
of ways: protocol timing, information requested from the server, information
|
||||||
|
required of the server, defaults to use if the server does not provide
|
||||||
|
certain information, values with which to override information provided by
|
||||||
|
the server, or values to prepend or append to information provided by the
|
||||||
|
server.
|
||||||
|
The configuration file can also be preinitialized with addresses to
|
||||||
|
use on networks that don't have DHCP servers.
|
||||||
|
.Sh PROTOCOL TIMING
|
||||||
|
The timing behaviour of the client need not be configured by the user.
|
||||||
|
If no timing configuration is provided by the user, a fairly
|
||||||
|
reasonable timing behaviour will be used by default \- one which
|
||||||
|
results in fairly timely updates without placing an inordinate load on
|
||||||
|
the server.
|
||||||
|
.Pp
|
||||||
|
The following statements can be used to adjust the timing behaviour of
|
||||||
|
the DHCP client if required, however:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic timeout Ar time ;
|
||||||
|
The
|
||||||
|
.Ic timeout
|
||||||
|
statement determines the amount of time that must pass between the
|
||||||
|
time that the client begins to try to determine its address and the
|
||||||
|
time that it decides that it's not going to be able to contact a server.
|
||||||
|
By default, this timeout is sixty seconds.
|
||||||
|
After the timeout has passed, if there are any static leases defined in the
|
||||||
|
configuration file, or any leases remaining in the lease database that
|
||||||
|
have not yet expired, the client will loop through these leases
|
||||||
|
attempting to validate them, and if it finds one that appears to be
|
||||||
|
valid, it will use that lease's address.
|
||||||
|
If there are no valid static leases or unexpired leases in the lease database,
|
||||||
|
the client will restart the protocol after the defined retry interval.
|
||||||
|
.It Ic retry Ar time ;
|
||||||
|
The
|
||||||
|
.Ic retry
|
||||||
|
statement determines the time that must pass after the client has
|
||||||
|
determined that there is no DHCP server present before it tries again
|
||||||
|
to contact a DHCP server.
|
||||||
|
By default, this is five minutes.
|
||||||
|
.It Ic select-timeout Ar time ;
|
||||||
|
It is possible (some might say desirable) for there to be more than
|
||||||
|
one DHCP server serving any given network.
|
||||||
|
In this case, it is possible that a client may be sent more than one offer
|
||||||
|
in response to its initial lease discovery message.
|
||||||
|
It may be that one of these offers is preferable to the other
|
||||||
|
(e.g., one offer may have the address the client previously used,
|
||||||
|
and the other may not).
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ic select-timeout
|
||||||
|
is the time after the client sends its first lease discovery request
|
||||||
|
at which it stops waiting for offers from servers, assuming that it
|
||||||
|
has received at least one such offer.
|
||||||
|
If no offers have been received by the time the
|
||||||
|
.Ic select-timeout
|
||||||
|
has expired, the client will accept the first offer that arrives.
|
||||||
|
.Pp
|
||||||
|
By default, the
|
||||||
|
.Ic select-timeout
|
||||||
|
is zero seconds \- that is, the client will take the first offer it sees.
|
||||||
|
.It Ic reboot Ar time ;
|
||||||
|
When the client is restarted, it first tries to reacquire the last
|
||||||
|
address it had.
|
||||||
|
This is called the INIT-REBOOT state.
|
||||||
|
If it is still attached to the same network it was attached to when it last
|
||||||
|
ran, this is the quickest way to get started.
|
||||||
|
The
|
||||||
|
.Ic reboot
|
||||||
|
statement sets the time that must elapse after the client first tries
|
||||||
|
to reacquire its old address before it gives up and tries to discover
|
||||||
|
a new address.
|
||||||
|
By default, the reboot timeout is ten seconds.
|
||||||
|
.It Ic backoff-cutoff Ar time ;
|
||||||
|
The client uses an exponential backoff algorithm with some randomness,
|
||||||
|
so that if many clients try to configure themselves at the same time,
|
||||||
|
they will not make their requests in lockstep.
|
||||||
|
The
|
||||||
|
.Ic backoff-cutoff
|
||||||
|
statement determines the maximum amount of time that the client is
|
||||||
|
allowed to back off.
|
||||||
|
It defaults to two minutes.
|
||||||
|
.It Ic initial-interval Ar time ;
|
||||||
|
The
|
||||||
|
.Ic initial-interval
|
||||||
|
statement sets the amount of time between the first attempt to reach a
|
||||||
|
server and the second attempt to reach a server.
|
||||||
|
Each time a message is sent, the interval between messages is incremented by
|
||||||
|
twice the current interval multiplied by a random number between zero and one.
|
||||||
|
If it is greater than the backoff-cutoff amount, it is set to that
|
||||||
|
amount.
|
||||||
|
It defaults to ten seconds.
|
||||||
|
.El
|
||||||
|
.Sh LEASE REQUIREMENTS AND REQUESTS
|
||||||
|
The DHCP protocol allows the client to request that the server send it
|
||||||
|
specific information, and not send it other information that it is not
|
||||||
|
prepared to accept.
|
||||||
|
The protocol also allows the client to reject offers from servers if they
|
||||||
|
don't contain information the client needs, or if the information provided
|
||||||
|
is not satisfactory.
|
||||||
|
.Pp
|
||||||
|
There is a variety of data contained in offers that DHCP servers send
|
||||||
|
to DHCP clients.
|
||||||
|
The data that can be specifically requested is what are called
|
||||||
|
.Em DHCP Options .
|
||||||
|
DHCP Options are defined in
|
||||||
|
.Xr dhcp-options 5 .
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Xo
|
||||||
|
.Ic request Op Ar option
|
||||||
|
.Oo , Ar ... option Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic request
|
||||||
|
statement causes the client to request that any server responding to the
|
||||||
|
client send the client its values for the specified options.
|
||||||
|
Only the option names should be specified in the request statement \- not
|
||||||
|
option parameters.
|
||||||
|
.It Xo
|
||||||
|
.Ic require Op Ar option
|
||||||
|
.Oo , Ar ... option Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic require
|
||||||
|
statement lists options that must be sent in order for an offer to be accepted.
|
||||||
|
Offers that do not contain all the listed options will be ignored.
|
||||||
|
.It Xo
|
||||||
|
.Ic send No { Op Ar option declaration
|
||||||
|
.Oo , Ar ... option declaration Oc }
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic send
|
||||||
|
statement causes the client to send the specified options to the server with
|
||||||
|
the specified values.
|
||||||
|
These are full option declarations as described in
|
||||||
|
.Xr dhcp-options 5 .
|
||||||
|
Options that are always sent in the DHCP protocol should not be specified
|
||||||
|
here, except that the client can specify a
|
||||||
|
.Ar dhcp-lease-time
|
||||||
|
option other than the default requested lease time, which is two hours.
|
||||||
|
The other obvious use for this statement is to send information to the server
|
||||||
|
that will allow it to differentiate between this client and other
|
||||||
|
clients or kinds of clients.
|
||||||
|
.El
|
||||||
|
.Sh OPTION MODIFIERS
|
||||||
|
In some cases, a client may receive option data from the server which
|
||||||
|
is not really appropriate for that client, or may not receive
|
||||||
|
information that it needs, and for which a useful default value exists.
|
||||||
|
It may also receive information which is useful, but which needs to be
|
||||||
|
supplemented with local information.
|
||||||
|
To handle these needs, several option modifiers are available.
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Xo
|
||||||
|
.Ic default No { Op Ar option declaration
|
||||||
|
.Oo , Ar ... option declaration Oc }
|
||||||
|
.Xc
|
||||||
|
If for some set of options the client should use the value supplied by
|
||||||
|
the server, but needs to use some default value if no value was supplied
|
||||||
|
by the server, these values can be defined in the
|
||||||
|
.Ic default
|
||||||
|
statement.
|
||||||
|
.It Xo
|
||||||
|
.Ic supersede No { Op Ar option declaration
|
||||||
|
.Oo , Ar ... option declaration Oc }
|
||||||
|
.Xc
|
||||||
|
If for some set of options the client should always use its own value
|
||||||
|
rather than any value supplied by the server, these values can be defined
|
||||||
|
in the
|
||||||
|
.Ic supersede
|
||||||
|
statement.
|
||||||
|
.It Xo
|
||||||
|
.Ic prepend No { Op Ar option declaration
|
||||||
|
.Oo , Ar ... option declaration Oc }
|
||||||
|
.Xc
|
||||||
|
If for some set of options the client should use a value you supply,
|
||||||
|
and then use the values supplied by the server, if any,
|
||||||
|
these values can be defined in the
|
||||||
|
.Ic prepend
|
||||||
|
statement.
|
||||||
|
The
|
||||||
|
.Ic prepend
|
||||||
|
statement can only be used for options which allow more than one value to
|
||||||
|
be given.
|
||||||
|
This restriction is not enforced \- if violated, the results are unpredictable.
|
||||||
|
.It Xo
|
||||||
|
.Ic append No { Op Ar option declaration
|
||||||
|
.Oo , Ar ... option declaration Oc }
|
||||||
|
.Xc
|
||||||
|
If for some set of options the client should first use the values
|
||||||
|
supplied by the server, if any, and then use values you supply, these
|
||||||
|
values can be defined in the
|
||||||
|
.Ic append
|
||||||
|
statement.
|
||||||
|
The
|
||||||
|
.Ic append
|
||||||
|
statement can only be used for options which allow more than one value to
|
||||||
|
be given.
|
||||||
|
This restriction is not enforced \- if you ignore it,
|
||||||
|
the behaviour will be unpredictable.
|
||||||
|
.El
|
||||||
|
.Sh LEASE DECLARATIONS
|
||||||
|
The lease declaration:
|
||||||
|
.Pp
|
||||||
|
.Xo
|
||||||
|
.Ic \ \& lease No { Ar lease-declaration
|
||||||
|
.Oo Ar ... lease-declaration Oc }
|
||||||
|
.Xc
|
||||||
|
.Pp
|
||||||
|
The DHCP client may decide after some period of time (see
|
||||||
|
.Sx PROTOCOL TIMING )
|
||||||
|
that it is not going to succeed in contacting a server.
|
||||||
|
At that time, it consults its own database of old leases and tests each one
|
||||||
|
that has not yet timed out by pinging the listed router for that lease to
|
||||||
|
see if that lease could work.
|
||||||
|
It is possible to define one or more
|
||||||
|
.Em fixed
|
||||||
|
leases in the client configuration file for networks where there is no DHCP
|
||||||
|
or BOOTP service, so that the client can still automatically configure its
|
||||||
|
address.
|
||||||
|
This is done with the
|
||||||
|
.Ic lease
|
||||||
|
statement.
|
||||||
|
.Pp
|
||||||
|
NOTE: the lease statement is also used in the
|
||||||
|
.Pa dhclient.leases
|
||||||
|
file in order to record leases that have been received from DHCP servers.
|
||||||
|
Some of the syntax for leases as described below is only needed in the
|
||||||
|
.Pa dhclient.leases
|
||||||
|
file.
|
||||||
|
Such syntax is documented here for completeness.
|
||||||
|
.Pp
|
||||||
|
A lease statement consists of the lease keyword, followed by a left
|
||||||
|
curly brace, followed by one or more lease declaration statements,
|
||||||
|
followed by a right curly brace.
|
||||||
|
The following lease declarations are possible:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic bootp ;
|
||||||
|
The
|
||||||
|
.Ic bootp
|
||||||
|
statement is used to indicate that the lease was acquired using the
|
||||||
|
BOOTP protocol rather than the DHCP protocol.
|
||||||
|
It is never necessary to specify this in the client configuration file.
|
||||||
|
The client uses this syntax in its lease database file.
|
||||||
|
.It Ic interface Ar \&"string\&" ;
|
||||||
|
The
|
||||||
|
.Ic interface
|
||||||
|
lease statement is used to indicate the interface on which the lease is valid.
|
||||||
|
If set, this lease will only be tried on a particular interface.
|
||||||
|
When the client receives a lease from a server, it always records the
|
||||||
|
interface number on which it received that lease.
|
||||||
|
If predefined leases are specified in the
|
||||||
|
.Nm
|
||||||
|
file, the interface should also be specified, although this is not required.
|
||||||
|
.It Ic fixed-address Ar ip-address ;
|
||||||
|
The
|
||||||
|
.Ic fixed-address
|
||||||
|
statement is used to set the IP address of a particular lease.
|
||||||
|
This is required for all lease statements.
|
||||||
|
The IP address must be specified as a dotted quad (e.g., 12.34.56.78).
|
||||||
|
.It Ic filename Ar \&"string\&" ;
|
||||||
|
The
|
||||||
|
.Ic filename
|
||||||
|
statement specifies the name of the boot filename to use.
|
||||||
|
This is not used by the standard client configuration script, but is
|
||||||
|
included for completeness.
|
||||||
|
.It Ic server-name Ar \&"string\&" ;
|
||||||
|
The
|
||||||
|
.Ic server-name
|
||||||
|
statement specifies the name of the boot server name to use.
|
||||||
|
This is also not used by the standard client configuration script.
|
||||||
|
.It Ic option Ar option-declaration ;
|
||||||
|
The
|
||||||
|
.Ic option
|
||||||
|
statement is used to specify the value of an option supplied by the server,
|
||||||
|
or, in the case of predefined leases declared in
|
||||||
|
.Nm dhclient.conf ,
|
||||||
|
the value that the user wishes the client configuration script to use if the
|
||||||
|
predefined lease is used.
|
||||||
|
.It Ic script Ar \&"script-name\&" ;
|
||||||
|
The
|
||||||
|
.Ic script
|
||||||
|
statement is used to specify the pathname of the DHCP client configuration
|
||||||
|
script.
|
||||||
|
This script is used by the DHCP client to set each interface's initial
|
||||||
|
configuration prior to requesting an address, to test the address once it
|
||||||
|
has been offered, and to set the interface's final configuration once a
|
||||||
|
lease has been acquired.
|
||||||
|
If no lease is acquired, the script is used to test predefined leases, if
|
||||||
|
any, and also called once if no valid lease can be identified.
|
||||||
|
For more information, see
|
||||||
|
.Xr dhclient.leases 5 .
|
||||||
|
.It Ic medium Ar \&"media setup\&" ;
|
||||||
|
The
|
||||||
|
.Ic medium
|
||||||
|
statement can be used on systems where network interfaces cannot
|
||||||
|
automatically determine the type of network to which they are connected.
|
||||||
|
The media setup string is a system-dependent parameter which is passed
|
||||||
|
to the DHCP client configuration script when initializing the interface.
|
||||||
|
On
|
||||||
|
.Ux
|
||||||
|
and UNIX-like systems, the argument is passed on the ifconfig command line
|
||||||
|
when configuring the interface.
|
||||||
|
.Pp
|
||||||
|
The DHCP client automatically declares this parameter if it used a
|
||||||
|
media type (see the
|
||||||
|
.Ic media
|
||||||
|
statement) when configuring the interface in order to obtain a lease.
|
||||||
|
This statement should be used in predefined leases only if the network
|
||||||
|
interface requires media type configuration.
|
||||||
|
.It Ic renew Ar date ;
|
||||||
|
.It Ic rebind Ar date ;
|
||||||
|
.It Ic expire Ar date ;
|
||||||
|
The
|
||||||
|
.Ic renew
|
||||||
|
statement defines the time at which the DHCP client should begin trying to
|
||||||
|
contact its server to renew a lease that it is using.
|
||||||
|
The
|
||||||
|
.Ic rebind
|
||||||
|
statement defines the time at which the DHCP client should begin to try to
|
||||||
|
contact
|
||||||
|
.Em any
|
||||||
|
DHCP server in order to renew its lease.
|
||||||
|
The
|
||||||
|
.Ic expire
|
||||||
|
statement defines the time at which the DHCP client must stop using a lease
|
||||||
|
if it has not been able to contact a server in order to renew it.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
These declarations are automatically set in leases acquired by the
|
||||||
|
DHCP client, but must also be configured in predefined leases \- a
|
||||||
|
predefined lease whose expiry time has passed will not be used by the
|
||||||
|
DHCP client.
|
||||||
|
.Pp
|
||||||
|
Dates are specified as follows:
|
||||||
|
.Pp
|
||||||
|
.Ar \ \&<weekday>
|
||||||
|
.Sm off
|
||||||
|
.Ar <year> No / Ar <month> No / Ar <day>
|
||||||
|
.Ar <hour> : <minute> : <second>
|
||||||
|
.Sm on
|
||||||
|
.Pp
|
||||||
|
The weekday is present to make it easy for a human to tell when a
|
||||||
|
lease expires \- it's specified as a number from zero to six, with zero
|
||||||
|
being Sunday.
|
||||||
|
When declaring a predefined lease, it can always be specified as zero.
|
||||||
|
The year is specified with the century, so it should generally be four
|
||||||
|
digits except for really long leases.
|
||||||
|
The month is specified as a number starting with 1 for January.
|
||||||
|
The day of the month is likewise specified starting with 1.
|
||||||
|
The hour is a number between 0 and 23,
|
||||||
|
the minute a number between 0 and 59,
|
||||||
|
and the second also a number between 0 and 59.
|
||||||
|
.Sh ALIAS DECLARATIONS
|
||||||
|
.Ic alias No { Ar declarations ... No }
|
||||||
|
.Pp
|
||||||
|
Some DHCP clients running TCP/IP roaming protocols may require that in
|
||||||
|
addition to the lease they may acquire via DHCP, their interface also
|
||||||
|
be configured with a predefined IP alias so that they can have a
|
||||||
|
permanent IP address even while roaming.
|
||||||
|
The Internet Software Consortium DHCP client doesn't support roaming with
|
||||||
|
fixed addresses directly, but in order to facilitate such experimentation,
|
||||||
|
the DHCP client can be set up to configure an IP alias using the
|
||||||
|
.Ic alias
|
||||||
|
declaration.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ic alias
|
||||||
|
declaration resembles a lease declaration, except that options other than
|
||||||
|
the subnet-mask option are ignored by the standard client configuration
|
||||||
|
script, and expiry times are ignored.
|
||||||
|
A typical alias declaration includes an interface declaration, a fixed-address
|
||||||
|
declaration for the IP alias address, and a subnet-mask option declaration.
|
||||||
|
A medium statement should never be included in an alias declaration.
|
||||||
|
.Sh OTHER DECLARATIONS
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic reject Ar ip-address ;
|
||||||
|
The
|
||||||
|
.Ic reject
|
||||||
|
statement causes the DHCP client to reject offers from servers who use
|
||||||
|
the specified address as a server identifier.
|
||||||
|
This can be used to avoid being configured by rogue or misconfigured DHCP
|
||||||
|
servers, although it should be a last resort \- better to track down
|
||||||
|
the bad DHCP server and fix it.
|
||||||
|
.It Xo
|
||||||
|
.Ic interface Ar \&"name\&" No { Ar declarations
|
||||||
|
.Ar ... No }
|
||||||
|
.Xc
|
||||||
|
A client with more than one network interface may require different
|
||||||
|
behaviour depending on which interface is being configured.
|
||||||
|
All timing parameters and declarations other than lease and alias
|
||||||
|
declarations can be enclosed in an interface declaration, and those
|
||||||
|
parameters will then be used only for the interface that matches the
|
||||||
|
specified name.
|
||||||
|
Interfaces for which there is no interface declaration will use the
|
||||||
|
parameters declared outside of any interface declaration,
|
||||||
|
or the default settings.
|
||||||
|
.It Xo
|
||||||
|
.Ic media Ar \&"media setup\&"
|
||||||
|
.Oo , Ar \&"media setup\&" , ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic media
|
||||||
|
statement defines one or more media configuration parameters which may
|
||||||
|
be tried while attempting to acquire an IP address.
|
||||||
|
The DHCP client will cycle through each media setup string on the list,
|
||||||
|
configuring the interface using that setup and attempting to boot,
|
||||||
|
and then trying the next one.
|
||||||
|
This can be used for network interfaces which aren't capable of sensing
|
||||||
|
the media type unaided \- whichever media type succeeds in getting a request
|
||||||
|
to the server and hearing the reply is probably right (no guarantees).
|
||||||
|
.Pp
|
||||||
|
The media setup is only used for the initial phase of address
|
||||||
|
acquisition (the DHCPDISCOVER and DHCPOFFER packets).
|
||||||
|
Once an address has been acquired, the DHCP client will record it in its
|
||||||
|
lease database and will record the media type used to acquire the address.
|
||||||
|
Whenever the client tries to renew the lease, it will use that same media type.
|
||||||
|
The lease must expire before the client will go back to cycling through media
|
||||||
|
types.
|
||||||
|
.El
|
||||||
|
.Sh EXAMPLES
|
||||||
|
The following configuration file is used on a laptop
|
||||||
|
which has an IP alias of 192.5.5.213, and has one interface,
|
||||||
|
ep0 (a 3Com 3C589C).
|
||||||
|
Booting intervals have been shortened somewhat from the default, because
|
||||||
|
the client is known to spend most of its time on networks with little DHCP
|
||||||
|
activity.
|
||||||
|
The laptop does roam to multiple networks.
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
timeout 60;
|
||||||
|
retry 60;
|
||||||
|
reboot 10;
|
||||||
|
select-timeout 5;
|
||||||
|
initial-interval 2;
|
||||||
|
reject 192.33.137.209;
|
||||||
|
|
||||||
|
interface "ep0" {
|
||||||
|
send host-name "andare.fugue.com";
|
||||||
|
send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
|
||||||
|
send dhcp-lease-time 3600;
|
||||||
|
supersede domain-name "fugue.com rc.vix.com home.vix.com";
|
||||||
|
prepend domain-name-servers 127.0.0.1;
|
||||||
|
request subnet-mask, broadcast-address, time-offset, routers,
|
||||||
|
domain-name, domain-name-servers, host-name;
|
||||||
|
require subnet-mask, domain-name-servers;
|
||||||
|
script "/etc/dhclient-script";
|
||||||
|
media "media 10baseT/UTP", "media 10base2/BNC";
|
||||||
|
}
|
||||||
|
|
||||||
|
alias {
|
||||||
|
interface "ep0";
|
||||||
|
fixed-address 192.5.5.213;
|
||||||
|
option subnet-mask 255.255.255.255;
|
||||||
|
}
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
This is a very complicated
|
||||||
|
.Nm
|
||||||
|
file \- in general, yours should be much simpler.
|
||||||
|
In many cases, it's sufficient to just create an empty
|
||||||
|
.Nm
|
||||||
|
file \- the defaults are usually fine.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr dhclient.leases 5 ,
|
||||||
|
.Xr dhcp-options 5 ,
|
||||||
|
.Xr dhcpd.conf 5 ,
|
||||||
|
.Xr dhclient 8 ,
|
||||||
|
.Xr dhcpd 8
|
||||||
|
.Pp
|
||||||
|
RFC 2132, RFC 2131.
|
||||||
|
.Sh AUTHORS
|
||||||
|
.Xr dhclient 8
|
||||||
|
was written by
|
||||||
|
.An Ted Lemon Aq mellon@vix.com
|
||||||
|
under a contract with Vixie Labs.
|
||||||
|
.Pp
|
||||||
|
The current implementation was reworked by
|
||||||
|
.An Henning Brauer Aq henning@openbsd.org .
|
87
sbin/dhclient/dhclient.leases.5
Normal file
87
sbin/dhclient/dhclient.leases.5
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
.\" $OpenBSD: dhclient.leases.5,v 1.4 2004/04/15 08:59:47 jmc Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1997 The Internet Software Consortium.
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\"
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" This software has been written for the Internet Software Consortium
|
||||||
|
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
.\" Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
|
||||||
|
.\" Enterprises, see ``http://www.vix.com''.
|
||||||
|
.\"
|
||||||
|
.Dd January 1, 1997
|
||||||
|
.Dt DHCLIENT.LEASES 5
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dhclient.leases
|
||||||
|
.Nd DHCP client lease database
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The Internet Software Consortium DHCP client keeps a persistent
|
||||||
|
database of leases that it has acquired that are still valid.
|
||||||
|
The database is a free-form ASCII file containing one valid declaration
|
||||||
|
per lease.
|
||||||
|
If more than one declaration appears for a given lease,
|
||||||
|
the last one in the file is used.
|
||||||
|
The file is written as a log, so this is not an unusual occurrence.
|
||||||
|
.Pp
|
||||||
|
The lease file is named
|
||||||
|
.Qq dhclient.leases.IFNAME ,
|
||||||
|
where
|
||||||
|
.Qq IFNAME
|
||||||
|
represents the network interface the DHCP client acquired the lease on.
|
||||||
|
For example, if
|
||||||
|
.Xr dhclient 8
|
||||||
|
is configured for the em0 network device,
|
||||||
|
the lease file will be named
|
||||||
|
.Qq dhclient.leases.em0 .
|
||||||
|
.Pp
|
||||||
|
The format of the lease declarations is described in
|
||||||
|
.Xr dhclient.conf 5 .
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width "/var/db/dhclient.leases.IFNAME "
|
||||||
|
.It /var/db/dhclient.leases.IFNAME
|
||||||
|
Current lease file.
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr dhclient.conf 5 ,
|
||||||
|
.Xr dhcp-options 5 ,
|
||||||
|
.Xr dhcpd.conf 5 ,
|
||||||
|
.Xr dhclient 8 ,
|
||||||
|
.Xr dhcpd 8
|
||||||
|
.Pp
|
||||||
|
RFC 2132, RFC 2131.
|
||||||
|
.Sh AUTHORS
|
||||||
|
.Xr dhclient 8
|
||||||
|
was written by
|
||||||
|
.An Ted Lemon Aq mellon@vix.com
|
||||||
|
under a contract with Vixie Labs.
|
||||||
|
.Pp
|
||||||
|
The current implementation was reworked by
|
||||||
|
.An Henning Brauer Aq henning@openbsd.org .
|
590
sbin/dhclient/dhcp-options.5
Normal file
590
sbin/dhclient/dhcp-options.5
Normal file
@ -0,0 +1,590 @@
|
|||||||
|
.\" $OpenBSD: dhcp-options.5,v 1.5 2005/03/02 15:30:42 jmc Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\"
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" This software has been written for the Internet Software Consortium
|
||||||
|
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
.\" Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
|
||||||
|
.\" Enterprises, see ``http://www.vix.com''.
|
||||||
|
.\"
|
||||||
|
.Dd January 1, 1995
|
||||||
|
.Dt DHCP-OPTIONS 5
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dhcp-options
|
||||||
|
.Nd Dynamic Host Configuration Protocol options
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The Dynamic Host Configuration protocol allows the client to receive
|
||||||
|
.Ic options
|
||||||
|
from the DHCP server describing the network configuration and various
|
||||||
|
services that are available on the network.
|
||||||
|
When configuring
|
||||||
|
.Xr dhcpd 8
|
||||||
|
or
|
||||||
|
.Xr dhclient 8 ,
|
||||||
|
options must often be declared.
|
||||||
|
The syntax for declaring options, and the names and formats of the options
|
||||||
|
that can be declared, are documented here.
|
||||||
|
.Sh REFERENCE: OPTION STATEMENTS
|
||||||
|
DHCP
|
||||||
|
.Ic option
|
||||||
|
statements always start with the
|
||||||
|
.Ic option
|
||||||
|
keyword, followed by an option name, followed by option data.
|
||||||
|
The option names and data formats are described below.
|
||||||
|
It is not necessary to exhaustively specify all DHCP options \-
|
||||||
|
only those options which are needed by clients must be specified.
|
||||||
|
.Pp
|
||||||
|
Option data comes in a variety of formats, as defined below:
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ar ip-address
|
||||||
|
data type can be entered either as an explicit IP address
|
||||||
|
(e.g., 239.254.197.10) or as a domain name (e.g., haagen.isc.org).
|
||||||
|
A domain name must resolve to a single IP address.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ar int32
|
||||||
|
data type specifies a signed 32-bit integer.
|
||||||
|
The
|
||||||
|
.Ar uint32
|
||||||
|
data type specifies an unsigned 32-bit integer.
|
||||||
|
The
|
||||||
|
.Ar int16
|
||||||
|
and
|
||||||
|
.Ar uint16
|
||||||
|
data types specify signed and unsigned 16-bit integers.
|
||||||
|
The
|
||||||
|
.Ar int8
|
||||||
|
and
|
||||||
|
.Ar uint8
|
||||||
|
data types specify signed and unsigned 8-bit integers.
|
||||||
|
Unsigned 8-bit integers are also sometimes referred to as octets.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ar string
|
||||||
|
data type specifies an
|
||||||
|
.Tn NVT
|
||||||
|
.Pq Network Virtual Terminal
|
||||||
|
.Tn ASCII
|
||||||
|
string, which must be enclosed in double quotes \- for example,
|
||||||
|
to specify a domain-name option, the syntax would be
|
||||||
|
.Pp
|
||||||
|
.Dl option domain-name \&"isc.org\&";
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ar flag
|
||||||
|
data type specifies a boolean value.
|
||||||
|
Booleans can be either true or false
|
||||||
|
(or on or off, if that makes more sense to you).
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ar data-string
|
||||||
|
data type specifies either an
|
||||||
|
.Tn NVT ASCII
|
||||||
|
string enclosed in double quotes, or a series of octets specified in
|
||||||
|
hexadecimal, separated by colons.
|
||||||
|
For example:
|
||||||
|
.Pp
|
||||||
|
.Dl option dhcp-client-identifier \&"CLIENT-FOO\&";
|
||||||
|
or
|
||||||
|
.Dl option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
|
||||||
|
.Pp
|
||||||
|
The documentation for the various options mentioned below is taken
|
||||||
|
from the IETF draft document on DHCP options, RFC 2132.
|
||||||
|
Options which are not listed by name may be defined by the name
|
||||||
|
.Pf option\- Ns Ar nnn ,
|
||||||
|
where
|
||||||
|
.Ar nnn
|
||||||
|
is the decimal number of the option code.
|
||||||
|
These options may be followed either by a string, enclosed in quotes, or by
|
||||||
|
a series of octets, expressed as two-digit hexadecimal numbers separated
|
||||||
|
by colons.
|
||||||
|
For example:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
option option-133 "my-option-133-text";
|
||||||
|
option option-129 1:54:c9:2b:47;
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Because
|
||||||
|
.Xr dhcpd 8
|
||||||
|
does not know the format of these undefined option codes,
|
||||||
|
no checking is done to ensure the correctness of the entered data.
|
||||||
|
.Pp
|
||||||
|
The standard options are:
|
||||||
|
.Ss RFC 1497 Vendor Extensions
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic option subnet-mask Ar ip-address ;
|
||||||
|
The
|
||||||
|
.Ic subnet-mask
|
||||||
|
option specifies the client's subnet mask as per RFC 950.
|
||||||
|
If no subnet-mask option is provided anywhere in scope, as a last resort
|
||||||
|
.Xr dhcpd 8
|
||||||
|
will use the subnet mask from the subnet declaration for the network on
|
||||||
|
which an address is being assigned.
|
||||||
|
However,
|
||||||
|
.Em any
|
||||||
|
subnet-mask option declaration that is in scope for the address being
|
||||||
|
assigned will override the subnet mask specified in the subnet declaration.
|
||||||
|
.It Ic option time-offset Ar int32 ;
|
||||||
|
The
|
||||||
|
.Ic time-offset
|
||||||
|
option specifies the offset of the client's subnet in seconds from
|
||||||
|
Coordinated Universal Time (UTC).
|
||||||
|
.It Xo
|
||||||
|
.Ic option routers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic routers
|
||||||
|
option specifies a list of IP addresses for routers on the client's subnet.
|
||||||
|
Routers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option time-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic time-server
|
||||||
|
option specifies a list of RFC 868 time servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option ien116-name-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic ien116-name-servers
|
||||||
|
option specifies a list of IEN 116 name servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option domain-name-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic domain-name-servers
|
||||||
|
option specifies a list of Domain Name System (STD 13, RFC 1035) name servers
|
||||||
|
available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option log-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic log-servers
|
||||||
|
option specifies a list of MIT-LCS UDP log servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option cookie-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic cookie-servers
|
||||||
|
option specifies a list of RFC 865 cookie servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option lpr-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic lpr-servers
|
||||||
|
option specifies a list of RFC 1179 line printer servers available to the
|
||||||
|
client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option impress-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic impress-servers
|
||||||
|
option specifies a list of Imagen Impress servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option resource-location-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a list of RFC 887 Resource Location servers available
|
||||||
|
to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Ic option host-name Ar string ;
|
||||||
|
This option specifies the name of the client.
|
||||||
|
The name may or may not be qualified with the local domain name
|
||||||
|
(it is preferable to use the
|
||||||
|
.Ic domain-name
|
||||||
|
option to specify the domain name).
|
||||||
|
See RFC 1035 for character set restrictions.
|
||||||
|
.It Ic option boot-size Ar uint16 ;
|
||||||
|
This option specifies the length in 512-octet blocks of the default
|
||||||
|
boot image for the client.
|
||||||
|
.It Ic option merit-dump Ar string ;
|
||||||
|
This option specifies the pathname of a file to which the client's
|
||||||
|
core image should be dumped in the event the client crashes.
|
||||||
|
The path is formatted as a character string consisting of characters from
|
||||||
|
the
|
||||||
|
.Tn NVT ASCII
|
||||||
|
character set.
|
||||||
|
.It Ic option domain-name Ar string ;
|
||||||
|
This option specifies the domain name that the client should use when
|
||||||
|
resolving hostnames via the Domain Name System.
|
||||||
|
.It Ic option swap-server Ar ip-address ;
|
||||||
|
This specifies the IP address of the client's swap server.
|
||||||
|
.It Ic option root-path Ar string ;
|
||||||
|
This option specifies the pathname that contains the client's root disk.
|
||||||
|
The path is formatted as a character string consisting of characters from
|
||||||
|
the
|
||||||
|
.Tn NVT ASCII
|
||||||
|
character set.
|
||||||
|
.El
|
||||||
|
.Ss IP Layer Parameters per Host
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic option ip-forwarding Ar flag ;
|
||||||
|
This option specifies whether the client should configure its IP layer
|
||||||
|
for packet forwarding.
|
||||||
|
A value of 0 means disable IP forwarding, and a value of 1 means enable
|
||||||
|
IP forwarding.
|
||||||
|
.It Ic option non-local-source-routing Ar flag ;
|
||||||
|
This option specifies whether the client should configure its IP
|
||||||
|
layer to allow forwarding of datagrams with non-local source routes
|
||||||
|
(see Section 3.3.5 of [4] for a discussion of this topic).
|
||||||
|
A value of 0 means disallow forwarding of such datagrams, and a value of 1
|
||||||
|
means allow forwarding.
|
||||||
|
.It Xo
|
||||||
|
.Ic option policy-filter Ar ip-address ip-address
|
||||||
|
.Oo , Ar ip-address ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies policy filters for non-local source routing.
|
||||||
|
The filters consist of a list of IP addresses and masks which specify
|
||||||
|
destination/mask pairs with which to filter incoming source routes.
|
||||||
|
.Pp
|
||||||
|
Any source-routed datagram whose next-hop address does not match one
|
||||||
|
of the filters should be discarded by the client.
|
||||||
|
.Pp
|
||||||
|
See STD 3 (RFC 1122) for further information.
|
||||||
|
.It Ic option max-dgram-reassembly Ar uint16 ;
|
||||||
|
This option specifies the maximum size datagram that the client should be
|
||||||
|
prepared to reassemble.
|
||||||
|
The minimum legal value is 576.
|
||||||
|
.It Ic option default-ip-ttl Ar uint8 ;
|
||||||
|
This option specifies the default time-to-live that the client should
|
||||||
|
use on outgoing datagrams.
|
||||||
|
.It Ic option path-mtu-aging-timeout Ar uint32 ;
|
||||||
|
This option specifies the timeout (in seconds) to use when aging Path
|
||||||
|
MTU values discovered by the mechanism defined in RFC 1191.
|
||||||
|
.It Xo
|
||||||
|
.Ic option path-mtu-plateau-table Ar uint16
|
||||||
|
.Oo , Ar uint16 ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a table of MTU sizes to use when performing
|
||||||
|
Path MTU Discovery as defined in RFC 1191.
|
||||||
|
The table is formatted as a list of 16-bit unsigned integers,
|
||||||
|
ordered from smallest to largest.
|
||||||
|
The minimum MTU value cannot be smaller than 68.
|
||||||
|
.El
|
||||||
|
.Ss IP Layer Parameters per Interface
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic option interface-mtu Ar uint16 ;
|
||||||
|
This option specifies the MTU to use on this interface.
|
||||||
|
The minimum legal value for the MTU is 68.
|
||||||
|
.It Ic option all-subnets-local Ar flag ;
|
||||||
|
This option specifies whether or not the client may assume that all subnets
|
||||||
|
of the IP network to which the client is connected use the same MTU as the
|
||||||
|
subnet of that network to which the client is directly connected.
|
||||||
|
A value of 1 indicates that all subnets share the same MTU.
|
||||||
|
A value of 0 means that the client should assume that some subnets of the
|
||||||
|
directly connected network may have smaller MTUs.
|
||||||
|
.It Ic option broadcast-address Ar ip-address ;
|
||||||
|
This option specifies the broadcast address in use on the client's subnet.
|
||||||
|
Legal values for broadcast addresses are specified in section 3.2.1.3 of
|
||||||
|
STD 3 (RFC 1122).
|
||||||
|
.It Ic option perform-mask-discovery Ar flag ;
|
||||||
|
This option specifies whether or not the client should perform subnet mask
|
||||||
|
discovery using ICMP.
|
||||||
|
A value of 0 indicates that the client should not perform mask discovery.
|
||||||
|
A value of 1 means that the client should perform mask discovery.
|
||||||
|
.It Ic option mask-supplier Ar flag ;
|
||||||
|
This option specifies whether or not the client should respond to subnet mask
|
||||||
|
requests using ICMP.
|
||||||
|
A value of 0 indicates that the client should not respond.
|
||||||
|
A value of 1 means that the client should respond.
|
||||||
|
.It Ic option router-discovery Ar flag ;
|
||||||
|
This option specifies whether or not the client should solicit routers using
|
||||||
|
the Router Discovery mechanism defined in RFC 1256.
|
||||||
|
A value of 0 indicates that the client should not perform router discovery.
|
||||||
|
A value of 1 means that the client should perform router discovery.
|
||||||
|
.It Ic option router-solicitation-address Ar ip-address ;
|
||||||
|
This option specifies the address to which the client should transmit
|
||||||
|
router solicitation requests.
|
||||||
|
.It Xo
|
||||||
|
.Ic option static-routes Ar ip-address ip-address
|
||||||
|
.Oo , Ar ip-address ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a list of static routes that the client should
|
||||||
|
install in its routing cache.
|
||||||
|
If multiple routes to the same destination are specified, they are listed
|
||||||
|
in descending order of priority.
|
||||||
|
.Pp
|
||||||
|
The routes consist of a list of IP address pairs.
|
||||||
|
The first address is the destination address,
|
||||||
|
and the second address is the router for the destination.
|
||||||
|
.Pp
|
||||||
|
The default route (0.0.0.0) is an illegal destination for a static route.
|
||||||
|
To specify the default route, use the
|
||||||
|
.Ic routers
|
||||||
|
option.
|
||||||
|
.El
|
||||||
|
.Ss Link Layer Parameters per Interface
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic option trailer-encapsulation Ar flag ;
|
||||||
|
This option specifies whether or not the client should negotiate the
|
||||||
|
use of trailers (RFC 893 [14]) when using the ARP protocol.
|
||||||
|
A value of 0 indicates that the client should not attempt to use trailers.
|
||||||
|
A value of 1 means that the client should attempt to use trailers.
|
||||||
|
.It Ic option arp-cache-timeout Ar uint32 ;
|
||||||
|
This option specifies the timeout in seconds for ARP cache entries.
|
||||||
|
.It Ic option ieee802-3-encapsulation Ar flag ;
|
||||||
|
This option specifies whether or not the client should use Ethernet
|
||||||
|
Version 2 (RFC 894) or IEEE 802.3 (RFC 1042) encapsulation if the
|
||||||
|
interface is an Ethernet.
|
||||||
|
A value of 0 indicates that the client should use RFC 894 encapsulation.
|
||||||
|
A value of 1 means that the client should use RFC 1042 encapsulation.
|
||||||
|
.El
|
||||||
|
.Ss TCP Parameters
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic option default-tcp-ttl Ar uint8 ;
|
||||||
|
This option specifies the default TTL that the client should use when
|
||||||
|
sending TCP segments.
|
||||||
|
The minimum value is 1.
|
||||||
|
.It Ic option tcp-keepalive-interval Ar uint32 ;
|
||||||
|
This option specifies the interval (in seconds) that the client TCP
|
||||||
|
should wait before sending a keepalive message on a TCP connection.
|
||||||
|
The time is specified as a 32-bit unsigned integer.
|
||||||
|
A value of zero indicates that the client should not generate keepalive
|
||||||
|
messages on connections unless specifically requested by an application.
|
||||||
|
.It Ic option tcp-keepalive-garbage Ar flag ;
|
||||||
|
This option specifies whether or not the client should send TCP keepalive
|
||||||
|
messages with an octet of garbage for compatibility with older implementations.
|
||||||
|
A value of 0 indicates that a garbage octet should not be sent.
|
||||||
|
A value of 1 indicates that a garbage octet should be sent.
|
||||||
|
.El
|
||||||
|
.Ss Application and Service Parameters
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic option nis-domain Ar string ;
|
||||||
|
This option specifies the name of the client's NIS (Sun Network Information
|
||||||
|
Services) domain.
|
||||||
|
The domain is formatted as a character string consisting of characters
|
||||||
|
from the
|
||||||
|
.Tn NVT ASCII
|
||||||
|
character set.
|
||||||
|
.It Xo
|
||||||
|
.Ic option nis-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a list of IP addresses indicating NIS servers
|
||||||
|
available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option ntp-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a list of IP addresses indicating NTP (RFC 1035)
|
||||||
|
servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option netbios-name-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The NetBIOS name server (NBNS) option specifies a list of RFC 1001/1002
|
||||||
|
NBNS name servers listed in order of preference.
|
||||||
|
NetBIOS Name Service is currently more commonly referred to as WINS.
|
||||||
|
WINS servers can be specified using the
|
||||||
|
.Ic netbios-name-servers
|
||||||
|
option.
|
||||||
|
.It Xo
|
||||||
|
.Ic option netbios-dd-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The NetBIOS datagram distribution server (NBDD) option specifies a
|
||||||
|
list of RFC 1001/1002 NBDD servers listed in order of preference.
|
||||||
|
.It Ic option netbios-node-type Ar uint8 ;
|
||||||
|
The NetBIOS node type option allows NetBIOS over TCP/IP clients which
|
||||||
|
are configurable to be configured as described in RFC 1001/1002.
|
||||||
|
The value is specified as a single octet which identifies the client type.
|
||||||
|
.Pp
|
||||||
|
Possible node types are:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It 1
|
||||||
|
B-node: Broadcast - no WINS
|
||||||
|
.It 2
|
||||||
|
P-node: Peer - WINS only
|
||||||
|
.It 4
|
||||||
|
M-node: Mixed - broadcast, then WINS
|
||||||
|
.It 8
|
||||||
|
H-node: Hybrid - WINS, then broadcast
|
||||||
|
.El
|
||||||
|
.It Ic option netbios-scope Ar string ;
|
||||||
|
The NetBIOS scope option specifies the NetBIOS over TCP/IP scope
|
||||||
|
parameter for the client as specified in RFC 1001/1002.
|
||||||
|
See RFC 1001, RFC 1002, and RFC 1035 for character-set restrictions.
|
||||||
|
.It Xo
|
||||||
|
.Ic option font-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a list of X Window System Font servers available
|
||||||
|
to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option x-display-manager Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a list of systems that are running the X Window
|
||||||
|
System Display Manager and are available to the client.
|
||||||
|
Addresses should be listed in order of preference.
|
||||||
|
.It Ic option dhcp-client-identifier Ar data-string ;
|
||||||
|
This option can be used to specify a DHCP client identifier in a
|
||||||
|
host declaration, so that
|
||||||
|
.Xr dhcpd 8
|
||||||
|
can find the host record by matching against the client identifier.
|
||||||
|
.It Ic option nisplus-domain Ar string ;
|
||||||
|
This option specifies the name of the client's NIS+ domain.
|
||||||
|
The domain is formatted as a character string consisting of characters
|
||||||
|
from the
|
||||||
|
.Tn NVT ASCII
|
||||||
|
character set.
|
||||||
|
.It Xo
|
||||||
|
.Ic option nisplus-servers Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a list of IP addresses indicating NIS+ servers
|
||||||
|
available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Ic option tftp-server-name Ar string ;
|
||||||
|
This option is used to identify a TFTP server and, if supported by the
|
||||||
|
client, should have the same effect as the
|
||||||
|
.Ic server-name
|
||||||
|
declaration.
|
||||||
|
BOOTP clients are unlikely to support this option.
|
||||||
|
Some DHCP clients will support it, and others actually require it.
|
||||||
|
.It Ic option bootfile-name Ar string ;
|
||||||
|
This option is used to identify a bootstrap file.
|
||||||
|
If supported by the client, it should have the same effect as the
|
||||||
|
.Ic filename
|
||||||
|
declaration.
|
||||||
|
BOOTP clients are unlikely to support this option.
|
||||||
|
Some DHCP clients will support it, and others actually require it.
|
||||||
|
.It Xo
|
||||||
|
.Ic option mobile-ip-home-agent Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
This option specifies a list of IP addresses indicating mobile IP
|
||||||
|
home agents available to the client.
|
||||||
|
Agents should be listed in order of preference, although normally there
|
||||||
|
will be only one such agent.
|
||||||
|
.It Xo
|
||||||
|
.Ic option smtp-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic smtp-server
|
||||||
|
option specifies a list of SMTP servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option pop-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic pop-server
|
||||||
|
option specifies a list of POP3 servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option nntp-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic nntp-server
|
||||||
|
option specifies a list of NNTP servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option www-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic www-server
|
||||||
|
option specifies a list of WWW servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option finger-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic finger-server
|
||||||
|
option specifies a list of
|
||||||
|
.Xr finger 1
|
||||||
|
servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option irc-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic irc-server
|
||||||
|
option specifies a list of IRC servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option streettalk-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The
|
||||||
|
.Ic streettalk-server
|
||||||
|
option specifies a list of StreetTalk servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.It Xo
|
||||||
|
.Ic option streettalk-directory-assistance-server Ar ip-address
|
||||||
|
.Oo , Ar ip-address ... Oc ;
|
||||||
|
.Xc
|
||||||
|
The StreetTalk Directory Assistance (STDA) server option specifies a
|
||||||
|
list of STDA servers available to the client.
|
||||||
|
Servers should be listed in order of preference.
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr dhclient.conf 5 ,
|
||||||
|
.Xr dhcpd.conf 5 ,
|
||||||
|
.Xr dhcpd.leases 5 ,
|
||||||
|
.Xr dhclient 8 ,
|
||||||
|
.Xr dhcpd 8
|
||||||
|
.Pp
|
||||||
|
RFC 2131, RFC 2132.
|
||||||
|
.Sh AUTHORS
|
||||||
|
.Xr dhcpd 8
|
||||||
|
was written by
|
||||||
|
.An Ted Lemon Aq mellon@vix.com
|
||||||
|
under a contract with Vixie Labs.
|
||||||
|
.Pp
|
||||||
|
The current implementation was reworked by
|
||||||
|
.An Henning Brauer Aq henning@openbsd.org .
|
168
sbin/dhclient/dhcp.h
Normal file
168
sbin/dhclient/dhcp.h
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/* $OpenBSD: dhcp.h,v 1.5 2004/05/04 15:49:49 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Protocol structures... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DHCP_UDP_OVERHEAD (14 + /* Ethernet header */ \
|
||||||
|
20 + /* IP header */ \
|
||||||
|
8) /* UDP header */
|
||||||
|
#define DHCP_SNAME_LEN 64
|
||||||
|
#define DHCP_FILE_LEN 128
|
||||||
|
#define DHCP_FIXED_NON_UDP 236
|
||||||
|
#define DHCP_FIXED_LEN (DHCP_FIXED_NON_UDP + DHCP_UDP_OVERHEAD)
|
||||||
|
/* Everything but options. */
|
||||||
|
#define DHCP_MTU_MAX 1500
|
||||||
|
#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
|
||||||
|
|
||||||
|
#define BOOTP_MIN_LEN 300
|
||||||
|
#define DHCP_MIN_LEN 548
|
||||||
|
|
||||||
|
struct dhcp_packet {
|
||||||
|
u_int8_t op; /* Message opcode/type */
|
||||||
|
u_int8_t htype; /* Hardware addr type (see net/if_types.h) */
|
||||||
|
u_int8_t hlen; /* Hardware addr length */
|
||||||
|
u_int8_t hops; /* Number of relay agent hops from client */
|
||||||
|
u_int32_t xid; /* Transaction ID */
|
||||||
|
u_int16_t secs; /* Seconds since client started looking */
|
||||||
|
u_int16_t flags; /* Flag bits */
|
||||||
|
struct in_addr ciaddr; /* Client IP address (if already in use) */
|
||||||
|
struct in_addr yiaddr; /* Client IP address */
|
||||||
|
struct in_addr siaddr; /* IP address of next server to talk to */
|
||||||
|
struct in_addr giaddr; /* DHCP relay agent IP address */
|
||||||
|
unsigned char chaddr[16]; /* Client hardware address */
|
||||||
|
char sname[DHCP_SNAME_LEN]; /* Server name */
|
||||||
|
char file[DHCP_FILE_LEN]; /* Boot filename */
|
||||||
|
unsigned char options[DHCP_OPTION_LEN];
|
||||||
|
/* Optional parameters
|
||||||
|
(actual length dependent on MTU). */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* BOOTP (rfc951) message types */
|
||||||
|
#define BOOTREQUEST 1
|
||||||
|
#define BOOTREPLY 2
|
||||||
|
|
||||||
|
/* Possible values for flags field... */
|
||||||
|
#define BOOTP_BROADCAST 32768L
|
||||||
|
|
||||||
|
/* Possible values for hardware type (htype) field... */
|
||||||
|
#define HTYPE_ETHER 1 /* Ethernet */
|
||||||
|
#define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
|
||||||
|
#define HTYPE_FDDI 8 /* FDDI... */
|
||||||
|
|
||||||
|
/* Magic cookie validating dhcp options field (and bootp vendor
|
||||||
|
extensions field). */
|
||||||
|
#define DHCP_OPTIONS_COOKIE "\143\202\123\143"
|
||||||
|
|
||||||
|
/* DHCP Option codes: */
|
||||||
|
|
||||||
|
#define DHO_PAD 0
|
||||||
|
#define DHO_SUBNET_MASK 1
|
||||||
|
#define DHO_TIME_OFFSET 2
|
||||||
|
#define DHO_ROUTERS 3
|
||||||
|
#define DHO_TIME_SERVERS 4
|
||||||
|
#define DHO_NAME_SERVERS 5
|
||||||
|
#define DHO_DOMAIN_NAME_SERVERS 6
|
||||||
|
#define DHO_LOG_SERVERS 7
|
||||||
|
#define DHO_COOKIE_SERVERS 8
|
||||||
|
#define DHO_LPR_SERVERS 9
|
||||||
|
#define DHO_IMPRESS_SERVERS 10
|
||||||
|
#define DHO_RESOURCE_LOCATION_SERVERS 11
|
||||||
|
#define DHO_HOST_NAME 12
|
||||||
|
#define DHO_BOOT_SIZE 13
|
||||||
|
#define DHO_MERIT_DUMP 14
|
||||||
|
#define DHO_DOMAIN_NAME 15
|
||||||
|
#define DHO_SWAP_SERVER 16
|
||||||
|
#define DHO_ROOT_PATH 17
|
||||||
|
#define DHO_EXTENSIONS_PATH 18
|
||||||
|
#define DHO_IP_FORWARDING 19
|
||||||
|
#define DHO_NON_LOCAL_SOURCE_ROUTING 20
|
||||||
|
#define DHO_POLICY_FILTER 21
|
||||||
|
#define DHO_MAX_DGRAM_REASSEMBLY 22
|
||||||
|
#define DHO_DEFAULT_IP_TTL 23
|
||||||
|
#define DHO_PATH_MTU_AGING_TIMEOUT 24
|
||||||
|
#define DHO_PATH_MTU_PLATEAU_TABLE 25
|
||||||
|
#define DHO_INTERFACE_MTU 26
|
||||||
|
#define DHO_ALL_SUBNETS_LOCAL 27
|
||||||
|
#define DHO_BROADCAST_ADDRESS 28
|
||||||
|
#define DHO_PERFORM_MASK_DISCOVERY 29
|
||||||
|
#define DHO_MASK_SUPPLIER 30
|
||||||
|
#define DHO_ROUTER_DISCOVERY 31
|
||||||
|
#define DHO_ROUTER_SOLICITATION_ADDRESS 32
|
||||||
|
#define DHO_STATIC_ROUTES 33
|
||||||
|
#define DHO_TRAILER_ENCAPSULATION 34
|
||||||
|
#define DHO_ARP_CACHE_TIMEOUT 35
|
||||||
|
#define DHO_IEEE802_3_ENCAPSULATION 36
|
||||||
|
#define DHO_DEFAULT_TCP_TTL 37
|
||||||
|
#define DHO_TCP_KEEPALIVE_INTERVAL 38
|
||||||
|
#define DHO_TCP_KEEPALIVE_GARBAGE 39
|
||||||
|
#define DHO_NIS_DOMAIN 40
|
||||||
|
#define DHO_NIS_SERVERS 41
|
||||||
|
#define DHO_NTP_SERVERS 42
|
||||||
|
#define DHO_VENDOR_ENCAPSULATED_OPTIONS 43
|
||||||
|
#define DHO_NETBIOS_NAME_SERVERS 44
|
||||||
|
#define DHO_NETBIOS_DD_SERVER 45
|
||||||
|
#define DHO_NETBIOS_NODE_TYPE 46
|
||||||
|
#define DHO_NETBIOS_SCOPE 47
|
||||||
|
#define DHO_FONT_SERVERS 48
|
||||||
|
#define DHO_X_DISPLAY_MANAGER 49
|
||||||
|
#define DHO_DHCP_REQUESTED_ADDRESS 50
|
||||||
|
#define DHO_DHCP_LEASE_TIME 51
|
||||||
|
#define DHO_DHCP_OPTION_OVERLOAD 52
|
||||||
|
#define DHO_DHCP_MESSAGE_TYPE 53
|
||||||
|
#define DHO_DHCP_SERVER_IDENTIFIER 54
|
||||||
|
#define DHO_DHCP_PARAMETER_REQUEST_LIST 55
|
||||||
|
#define DHO_DHCP_MESSAGE 56
|
||||||
|
#define DHO_DHCP_MAX_MESSAGE_SIZE 57
|
||||||
|
#define DHO_DHCP_RENEWAL_TIME 58
|
||||||
|
#define DHO_DHCP_REBINDING_TIME 59
|
||||||
|
#define DHO_DHCP_CLASS_IDENTIFIER 60
|
||||||
|
#define DHO_DHCP_CLIENT_IDENTIFIER 61
|
||||||
|
#define DHO_DHCP_USER_CLASS_ID 77
|
||||||
|
#define DHO_END 255
|
||||||
|
|
||||||
|
/* DHCP message types. */
|
||||||
|
#define DHCPDISCOVER 1
|
||||||
|
#define DHCPOFFER 2
|
||||||
|
#define DHCPREQUEST 3
|
||||||
|
#define DHCPDECLINE 4
|
||||||
|
#define DHCPACK 5
|
||||||
|
#define DHCPNAK 6
|
||||||
|
#define DHCPRELEASE 7
|
||||||
|
#define DHCPINFORM 8
|
437
sbin/dhclient/dhcpd.h
Normal file
437
sbin/dhclient/dhcpd.h
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
/* $OpenBSD: dhcpd.h,v 1.33 2004/05/06 22:29:15 deraadt Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
|
||||||
|
* Copyright (c) 1995, 1996, 1997, 1998, 1999
|
||||||
|
* The Internet Software Consortium. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <paths.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dhcp.h"
|
||||||
|
#include "tree.h"
|
||||||
|
|
||||||
|
#define LOCAL_PORT 68
|
||||||
|
#define REMOTE_PORT 67
|
||||||
|
|
||||||
|
struct option_data {
|
||||||
|
int len;
|
||||||
|
u_int8_t *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct string_list {
|
||||||
|
struct string_list *next;
|
||||||
|
char *string;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iaddr {
|
||||||
|
int len;
|
||||||
|
unsigned char iabuf[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iaddrlist {
|
||||||
|
struct iaddrlist *next;
|
||||||
|
struct iaddr addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct packet {
|
||||||
|
struct dhcp_packet *raw;
|
||||||
|
int packet_length;
|
||||||
|
int packet_type;
|
||||||
|
int options_valid;
|
||||||
|
int client_port;
|
||||||
|
struct iaddr client_addr;
|
||||||
|
struct interface_info *interface;
|
||||||
|
struct hardware *haddr;
|
||||||
|
struct option_data options[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hardware {
|
||||||
|
u_int8_t htype;
|
||||||
|
u_int8_t hlen;
|
||||||
|
u_int8_t haddr[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct client_lease {
|
||||||
|
struct client_lease *next;
|
||||||
|
time_t expiry, renewal, rebind;
|
||||||
|
struct iaddr address;
|
||||||
|
char *server_name;
|
||||||
|
char *filename;
|
||||||
|
struct string_list *medium;
|
||||||
|
unsigned int is_static : 1;
|
||||||
|
unsigned int is_bootp : 1;
|
||||||
|
struct option_data options[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Possible states in which the client can be. */
|
||||||
|
enum dhcp_state {
|
||||||
|
S_REBOOTING,
|
||||||
|
S_INIT,
|
||||||
|
S_SELECTING,
|
||||||
|
S_REQUESTING,
|
||||||
|
S_BOUND,
|
||||||
|
S_RENEWING,
|
||||||
|
S_REBINDING
|
||||||
|
};
|
||||||
|
|
||||||
|
struct client_config {
|
||||||
|
struct option_data defaults[256];
|
||||||
|
enum {
|
||||||
|
ACTION_DEFAULT,
|
||||||
|
ACTION_SUPERSEDE,
|
||||||
|
ACTION_PREPEND,
|
||||||
|
ACTION_APPEND
|
||||||
|
} default_actions[256];
|
||||||
|
|
||||||
|
struct option_data send_options[256];
|
||||||
|
u_int8_t required_options[256];
|
||||||
|
u_int8_t requested_options[256];
|
||||||
|
int requested_option_count;
|
||||||
|
time_t timeout;
|
||||||
|
time_t initial_interval;
|
||||||
|
time_t retry_interval;
|
||||||
|
time_t select_interval;
|
||||||
|
time_t reboot_timeout;
|
||||||
|
time_t backoff_cutoff;
|
||||||
|
struct string_list *media;
|
||||||
|
char *script_name;
|
||||||
|
enum { IGNORE, ACCEPT, PREFER }
|
||||||
|
bootp_policy;
|
||||||
|
struct string_list *medium;
|
||||||
|
struct iaddrlist *reject_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct client_state {
|
||||||
|
struct client_lease *active;
|
||||||
|
struct client_lease *new;
|
||||||
|
struct client_lease *offered_leases;
|
||||||
|
struct client_lease *leases;
|
||||||
|
struct client_lease *alias;
|
||||||
|
enum dhcp_state state;
|
||||||
|
struct iaddr destination;
|
||||||
|
u_int32_t xid;
|
||||||
|
u_int16_t secs;
|
||||||
|
time_t first_sending;
|
||||||
|
time_t interval;
|
||||||
|
struct string_list *medium;
|
||||||
|
struct dhcp_packet packet;
|
||||||
|
int packet_length;
|
||||||
|
struct iaddr requested_address;
|
||||||
|
struct client_config *config;
|
||||||
|
char **scriptEnv;
|
||||||
|
int scriptEnvsize;
|
||||||
|
struct string_list *env;
|
||||||
|
int envc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct interface_info {
|
||||||
|
struct interface_info *next;
|
||||||
|
struct hardware hw_address;
|
||||||
|
struct in_addr primary_address;
|
||||||
|
char name[IFNAMSIZ];
|
||||||
|
int rfdesc;
|
||||||
|
int wfdesc;
|
||||||
|
unsigned char *rbuf;
|
||||||
|
size_t rbuf_max;
|
||||||
|
size_t rbuf_offset;
|
||||||
|
size_t rbuf_len;
|
||||||
|
struct ifreq *ifp;
|
||||||
|
struct client_state *client;
|
||||||
|
int noifmedia;
|
||||||
|
int errors;
|
||||||
|
int dead;
|
||||||
|
u_int16_t index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timeout {
|
||||||
|
struct timeout *next;
|
||||||
|
time_t when;
|
||||||
|
void (*func)(void *);
|
||||||
|
void *what;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct protocol {
|
||||||
|
struct protocol *next;
|
||||||
|
int fd;
|
||||||
|
void (*handler)(struct protocol *);
|
||||||
|
void *local;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFAULT_HASH_SIZE 97
|
||||||
|
|
||||||
|
struct hash_bucket {
|
||||||
|
struct hash_bucket *next;
|
||||||
|
unsigned char *name;
|
||||||
|
int len;
|
||||||
|
unsigned char *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hash_table {
|
||||||
|
int hash_count;
|
||||||
|
struct hash_bucket *buckets[DEFAULT_HASH_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Default path to dhcpd config file. */
|
||||||
|
#define _PATH_DHCLIENT_CONF "/etc/dhclient.conf"
|
||||||
|
#define _PATH_DHCLIENT_DB "/var/db/dhclient.leases"
|
||||||
|
#define DHCPD_LOG_FACILITY LOG_DAEMON
|
||||||
|
|
||||||
|
#define MAX_TIME 0x7fffffff
|
||||||
|
#define MIN_TIME 0
|
||||||
|
|
||||||
|
/* External definitions... */
|
||||||
|
|
||||||
|
/* options.c */
|
||||||
|
int cons_options(struct packet *, struct dhcp_packet *, int,
|
||||||
|
struct tree_cache **, int, int, int, u_int8_t *, int);
|
||||||
|
char *pretty_print_option(unsigned int,
|
||||||
|
unsigned char *, int, int, int);
|
||||||
|
void do_packet(struct interface_info *, struct dhcp_packet *,
|
||||||
|
int, unsigned int, struct iaddr, struct hardware *);
|
||||||
|
|
||||||
|
/* errwarn.c */
|
||||||
|
extern int warnings_occurred;
|
||||||
|
void error(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||||
|
int warning(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||||
|
int note(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||||
|
int debug(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||||
|
int parse_warn(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||||
|
|
||||||
|
/* conflex.c */
|
||||||
|
extern int lexline, lexchar;
|
||||||
|
extern char *token_line, *tlname;
|
||||||
|
extern char comments[4096];
|
||||||
|
extern int comment_index;
|
||||||
|
extern int eol_token;
|
||||||
|
void new_parse(char *);
|
||||||
|
int next_token(char **, FILE *);
|
||||||
|
int peek_token(char **, FILE *);
|
||||||
|
|
||||||
|
/* parse.c */
|
||||||
|
void skip_to_semi(FILE *);
|
||||||
|
int parse_semi(FILE *);
|
||||||
|
char *parse_string(FILE *);
|
||||||
|
int parse_ip_addr(FILE *, struct iaddr *);
|
||||||
|
void parse_hardware_param(FILE *, struct hardware *);
|
||||||
|
void parse_lease_time(FILE *, time_t *);
|
||||||
|
unsigned char *parse_numeric_aggregate(FILE *, unsigned char *, int *,
|
||||||
|
int, int, int);
|
||||||
|
void convert_num(unsigned char *, char *, int, int);
|
||||||
|
time_t parse_date(FILE *);
|
||||||
|
|
||||||
|
/* tree.c */
|
||||||
|
pair cons(caddr_t, pair);
|
||||||
|
|
||||||
|
/* alloc.c */
|
||||||
|
struct string_list *new_string_list(size_t size);
|
||||||
|
struct hash_table *new_hash_table(int);
|
||||||
|
struct hash_bucket *new_hash_bucket(void);
|
||||||
|
|
||||||
|
/* bpf.c */
|
||||||
|
int if_register_bpf(struct interface_info *);
|
||||||
|
void if_register_send(struct interface_info *);
|
||||||
|
void if_register_receive(struct interface_info *);
|
||||||
|
ssize_t send_packet(struct interface_info *, struct dhcp_packet *, size_t,
|
||||||
|
struct in_addr, struct sockaddr_in *, struct hardware *);
|
||||||
|
ssize_t receive_packet(struct interface_info *, unsigned char *, size_t,
|
||||||
|
struct sockaddr_in *, struct hardware *);
|
||||||
|
|
||||||
|
/* dispatch.c */
|
||||||
|
extern void (*bootp_packet_handler)(struct interface_info *,
|
||||||
|
struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *);
|
||||||
|
void discover_interfaces(struct interface_info *);
|
||||||
|
void reinitialize_interfaces(void);
|
||||||
|
void dispatch(void);
|
||||||
|
void got_one(struct protocol *);
|
||||||
|
void add_timeout(time_t, void (*)(void *), void *);
|
||||||
|
void cancel_timeout(void (*)(void *), void *);
|
||||||
|
void add_protocol(char *, int, void (*)(struct protocol *), void *);
|
||||||
|
void remove_protocol(struct protocol *);
|
||||||
|
int interface_link_status(char *);
|
||||||
|
|
||||||
|
/* hash.c */
|
||||||
|
struct hash_table *new_hash(void);
|
||||||
|
void add_hash(struct hash_table *, unsigned char *, int, unsigned char *);
|
||||||
|
unsigned char *hash_lookup(struct hash_table *, unsigned char *, int);
|
||||||
|
|
||||||
|
/* tables.c */
|
||||||
|
extern struct option dhcp_options[256];
|
||||||
|
extern unsigned char dhcp_option_default_priority_list[];
|
||||||
|
extern int sizeof_dhcp_option_default_priority_list;
|
||||||
|
extern struct hash_table universe_hash;
|
||||||
|
extern struct universe dhcp_universe;
|
||||||
|
void initialize_universes(void);
|
||||||
|
|
||||||
|
/* convert.c */
|
||||||
|
u_int32_t getULong(unsigned char *);
|
||||||
|
int32_t getLong(unsigned char *);
|
||||||
|
u_int16_t getUShort(unsigned char *);
|
||||||
|
int16_t getShort(unsigned char *);
|
||||||
|
void putULong(unsigned char *, u_int32_t);
|
||||||
|
void putLong(unsigned char *, int32_t);
|
||||||
|
void putUShort(unsigned char *, unsigned int);
|
||||||
|
void putShort(unsigned char *, int);
|
||||||
|
|
||||||
|
/* inet.c */
|
||||||
|
struct iaddr subnet_number(struct iaddr, struct iaddr);
|
||||||
|
struct iaddr broadcast_addr(struct iaddr, struct iaddr);
|
||||||
|
int addr_eq(struct iaddr, struct iaddr);
|
||||||
|
char *piaddr(struct iaddr);
|
||||||
|
|
||||||
|
/* dhclient.c */
|
||||||
|
extern char *path_dhclient_conf;
|
||||||
|
extern char *path_dhclient_db;
|
||||||
|
extern time_t cur_time;
|
||||||
|
extern int log_priority;
|
||||||
|
extern int log_perror;
|
||||||
|
|
||||||
|
extern struct client_config top_level_config;
|
||||||
|
|
||||||
|
void dhcpoffer(struct packet *);
|
||||||
|
void dhcpack(struct packet *);
|
||||||
|
void dhcpnak(struct packet *);
|
||||||
|
|
||||||
|
void send_discover(void *);
|
||||||
|
void send_request(void *);
|
||||||
|
void send_decline(void *);
|
||||||
|
|
||||||
|
void state_reboot(void *);
|
||||||
|
void state_init(void *);
|
||||||
|
void state_selecting(void *);
|
||||||
|
void state_requesting(void *);
|
||||||
|
void state_bound(void *);
|
||||||
|
void state_panic(void *);
|
||||||
|
|
||||||
|
void bind_lease(struct interface_info *);
|
||||||
|
|
||||||
|
void make_discover(struct interface_info *, struct client_lease *);
|
||||||
|
void make_request(struct interface_info *, struct client_lease *);
|
||||||
|
void make_decline(struct interface_info *, struct client_lease *);
|
||||||
|
|
||||||
|
void free_client_lease(struct client_lease *);
|
||||||
|
void rewrite_client_leases(void);
|
||||||
|
void write_client_lease(struct interface_info *, struct client_lease *, int);
|
||||||
|
|
||||||
|
void priv_script_init(char *, char *);
|
||||||
|
void priv_script_write_params(char *, struct client_lease *);
|
||||||
|
int priv_script_go(void);
|
||||||
|
|
||||||
|
void script_init(char *, struct string_list *);
|
||||||
|
void script_write_params(char *, struct client_lease *);
|
||||||
|
int script_go(void);
|
||||||
|
void client_envadd(struct client_state *,
|
||||||
|
const char *, const char *, const char *, ...);
|
||||||
|
void script_set_env(struct client_state *, const char *, const char *,
|
||||||
|
const char *);
|
||||||
|
void script_flush_env(struct client_state *);
|
||||||
|
int dhcp_option_ev_name(char *, size_t, struct option *);
|
||||||
|
|
||||||
|
struct client_lease *packet_to_lease(struct packet *);
|
||||||
|
void go_daemon(void);
|
||||||
|
void client_location_changed(void);
|
||||||
|
|
||||||
|
void bootp(struct packet *);
|
||||||
|
void dhcp(struct packet *);
|
||||||
|
|
||||||
|
/* packet.c */
|
||||||
|
void assemble_hw_header(struct interface_info *, unsigned char *,
|
||||||
|
int *, struct hardware *);
|
||||||
|
void assemble_udp_ip_header(unsigned char *, int *, u_int32_t, u_int32_t,
|
||||||
|
unsigned int, unsigned char *, int);
|
||||||
|
ssize_t decode_hw_header(unsigned char *, int, struct hardware *);
|
||||||
|
ssize_t decode_udp_ip_header(unsigned char *, int, struct sockaddr_in *,
|
||||||
|
unsigned char *, int);
|
||||||
|
|
||||||
|
/* ethernet.c */
|
||||||
|
void assemble_ethernet_header(struct interface_info *, unsigned char *,
|
||||||
|
int *, struct hardware *);
|
||||||
|
ssize_t decode_ethernet_header(struct interface_info *, unsigned char *,
|
||||||
|
int, struct hardware *);
|
||||||
|
|
||||||
|
/* clparse.c */
|
||||||
|
int read_client_conf(void);
|
||||||
|
void read_client_leases(void);
|
||||||
|
void parse_client_statement(FILE *, struct interface_info *,
|
||||||
|
struct client_config *);
|
||||||
|
int parse_X(FILE *, u_int8_t *, int);
|
||||||
|
int parse_option_list(FILE *, u_int8_t *);
|
||||||
|
void parse_interface_declaration(FILE *, struct client_config *);
|
||||||
|
struct interface_info *interface_or_dummy(char *);
|
||||||
|
void make_client_state(struct interface_info *);
|
||||||
|
void make_client_config(struct interface_info *, struct client_config *);
|
||||||
|
void parse_client_lease_statement(FILE *, int);
|
||||||
|
void parse_client_lease_declaration(FILE *, struct client_lease *,
|
||||||
|
struct interface_info **);
|
||||||
|
struct option *parse_option_decl(FILE *, struct option_data *);
|
||||||
|
void parse_string_list(FILE *, struct string_list **, int);
|
||||||
|
void parse_reject_statement(FILE *, struct client_config *);
|
||||||
|
|
||||||
|
/* privsep.c */
|
||||||
|
struct buf *buf_open(size_t);
|
||||||
|
int buf_add(struct buf *, void *, size_t);
|
||||||
|
int buf_close(int, struct buf *);
|
||||||
|
ssize_t buf_read(int, void *, size_t);
|
||||||
|
void dispatch_imsg(int);
|
136
sbin/dhclient/dhctoken.h
Normal file
136
sbin/dhclient/dhctoken.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/* $OpenBSD: dhctoken.h,v 1.2 2004/02/04 12:16:56 henning Exp $ */
|
||||||
|
|
||||||
|
/* Tokens for config file lexer and parser. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1997, 1998, 1999
|
||||||
|
* The Internet Software Consortium. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SEMI ';'
|
||||||
|
#define DOT '.'
|
||||||
|
#define COLON ':'
|
||||||
|
#define COMMA ','
|
||||||
|
#define SLASH '/'
|
||||||
|
#define LBRACE '{'
|
||||||
|
#define RBRACE '}'
|
||||||
|
|
||||||
|
#define FIRST_TOKEN HOST
|
||||||
|
#define HOST 256
|
||||||
|
#define HARDWARE 257
|
||||||
|
#define FILENAME 258
|
||||||
|
#define FIXED_ADDR 259
|
||||||
|
#define OPTION 260
|
||||||
|
#define ETHERNET 261
|
||||||
|
#define STRING 262
|
||||||
|
#define NUMBER 263
|
||||||
|
#define NUMBER_OR_NAME 264
|
||||||
|
#define NAME 265
|
||||||
|
#define TIMESTAMP 266
|
||||||
|
#define STARTS 267
|
||||||
|
#define ENDS 268
|
||||||
|
#define UID 269
|
||||||
|
#define CLASS 270
|
||||||
|
#define LEASE 271
|
||||||
|
#define RANGE 272
|
||||||
|
#define PACKET 273
|
||||||
|
#define CIADDR 274
|
||||||
|
#define YIADDR 275
|
||||||
|
#define SIADDR 276
|
||||||
|
#define GIADDR 277
|
||||||
|
#define SUBNET 278
|
||||||
|
#define NETMASK 279
|
||||||
|
#define DEFAULT_LEASE_TIME 280
|
||||||
|
#define MAX_LEASE_TIME 281
|
||||||
|
#define VENDOR_CLASS 282
|
||||||
|
#define USER_CLASS 283
|
||||||
|
#define SHARED_NETWORK 284
|
||||||
|
#define SERVER_NAME 285
|
||||||
|
#define DYNAMIC_BOOTP 286
|
||||||
|
#define SERVER_IDENTIFIER 287
|
||||||
|
#define DYNAMIC_BOOTP_LEASE_CUTOFF 288
|
||||||
|
#define DYNAMIC_BOOTP_LEASE_LENGTH 289
|
||||||
|
#define BOOT_UNKNOWN_CLIENTS 290
|
||||||
|
#define NEXT_SERVER 291
|
||||||
|
#define TOKEN_RING 292
|
||||||
|
#define GROUP 293
|
||||||
|
#define ONE_LEASE_PER_CLIENT 294
|
||||||
|
#define GET_LEASE_HOSTNAMES 295
|
||||||
|
#define USE_HOST_DECL_NAMES 296
|
||||||
|
#define SEND 297
|
||||||
|
#define CLIENT_IDENTIFIER 298
|
||||||
|
#define REQUEST 299
|
||||||
|
#define REQUIRE 300
|
||||||
|
#define TIMEOUT 301
|
||||||
|
#define RETRY 302
|
||||||
|
#define SELECT_TIMEOUT 303
|
||||||
|
#define SCRIPT 304
|
||||||
|
#define INTERFACE 305
|
||||||
|
#define RENEW 306
|
||||||
|
#define REBIND 307
|
||||||
|
#define EXPIRE 308
|
||||||
|
#define UNKNOWN_CLIENTS 309
|
||||||
|
#define ALLOW 310
|
||||||
|
#define BOOTP 311
|
||||||
|
#define DENY 312
|
||||||
|
#define BOOTING 313
|
||||||
|
#define DEFAULT 314
|
||||||
|
#define MEDIA 315
|
||||||
|
#define MEDIUM 316
|
||||||
|
#define ALIAS 317
|
||||||
|
#define REBOOT 318
|
||||||
|
#define ABANDONED 319
|
||||||
|
#define BACKOFF_CUTOFF 320
|
||||||
|
#define INITIAL_INTERVAL 321
|
||||||
|
#define NAMESERVER 322
|
||||||
|
#define DOMAIN 323
|
||||||
|
#define SEARCH 324
|
||||||
|
#define SUPERSEDE 325
|
||||||
|
#define APPEND 326
|
||||||
|
#define PREPEND 327
|
||||||
|
#define HOSTNAME 328
|
||||||
|
#define CLIENT_HOSTNAME 329
|
||||||
|
#define REJECT 330
|
||||||
|
#define FDDI 331
|
||||||
|
#define USE_LEASE_ADDR_FOR_DEFAULT_ROUTE 332
|
||||||
|
#define AUTHORITATIVE 333
|
||||||
|
#define TOKEN_NOT 334
|
||||||
|
#define ALWAYS_REPLY_RFC1048 335
|
||||||
|
|
||||||
|
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||||
|
(x) != STRING && \
|
||||||
|
(x) != NUMBER && \
|
||||||
|
(x) != EOF)
|
495
sbin/dhclient/dispatch.c
Normal file
495
sbin/dhclient/dispatch.c
Normal file
@ -0,0 +1,495 @@
|
|||||||
|
/* $OpenBSD: dispatch.c,v 1.31 2004/09/21 04:07:03 david Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2004 Henning Brauer <henning@openbsd.org>
|
||||||
|
* Copyright (c) 1995, 1996, 1997, 1998, 1999
|
||||||
|
* The Internet Software Consortium. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <net/if_media.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
struct protocol *protocols;
|
||||||
|
struct timeout *timeouts;
|
||||||
|
static struct timeout *free_timeouts;
|
||||||
|
static int interfaces_invalidated;
|
||||||
|
void (*bootp_packet_handler)(struct interface_info *,
|
||||||
|
struct dhcp_packet *, int, unsigned int,
|
||||||
|
struct iaddr, struct hardware *);
|
||||||
|
|
||||||
|
static int interface_status(struct interface_info *ifinfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use getifaddrs() to get a list of all the attached interfaces. For
|
||||||
|
* each interface that's of type INET and not the loopback interface,
|
||||||
|
* register that interface with the network I/O software, figure out
|
||||||
|
* what subnet it's on, and add it to the list of interfaces.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
discover_interfaces(struct interface_info *iface)
|
||||||
|
{
|
||||||
|
struct ifaddrs *ifap, *ifa;
|
||||||
|
struct sockaddr_in foo;
|
||||||
|
struct ifreq *tif;
|
||||||
|
|
||||||
|
if (getifaddrs(&ifap) != 0)
|
||||||
|
error("getifaddrs failed");
|
||||||
|
|
||||||
|
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
|
||||||
|
if ((ifa->ifa_flags & IFF_LOOPBACK) ||
|
||||||
|
(ifa->ifa_flags & IFF_POINTOPOINT) ||
|
||||||
|
(!(ifa->ifa_flags & IFF_UP)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(iface->name, ifa->ifa_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have the capability, extract link information
|
||||||
|
* and record it in a linked list.
|
||||||
|
*/
|
||||||
|
if (ifa->ifa_addr->sa_family == AF_LINK) {
|
||||||
|
struct sockaddr_dl *foo =
|
||||||
|
(struct sockaddr_dl *)ifa->ifa_addr;
|
||||||
|
|
||||||
|
iface->index = foo->sdl_index;
|
||||||
|
iface->hw_address.hlen = foo->sdl_alen;
|
||||||
|
iface->hw_address.htype = HTYPE_ETHER; /* XXX */
|
||||||
|
memcpy(iface->hw_address.haddr,
|
||||||
|
LLADDR(foo), foo->sdl_alen);
|
||||||
|
} else if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||||
|
struct iaddr addr;
|
||||||
|
|
||||||
|
memcpy(&foo, ifa->ifa_addr, sizeof(foo));
|
||||||
|
if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
|
||||||
|
continue;
|
||||||
|
if (!iface->ifp) {
|
||||||
|
int len = IFNAMSIZ + ifa->ifa_addr->sa_len;
|
||||||
|
if ((tif = malloc(len)) == NULL)
|
||||||
|
error("no space to remember ifp");
|
||||||
|
strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
|
||||||
|
memcpy(&tif->ifr_addr, ifa->ifa_addr,
|
||||||
|
ifa->ifa_addr->sa_len);
|
||||||
|
iface->ifp = tif;
|
||||||
|
iface->primary_address = foo.sin_addr;
|
||||||
|
}
|
||||||
|
addr.len = 4;
|
||||||
|
memcpy(addr.iabuf, &foo.sin_addr.s_addr, addr.len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iface->ifp)
|
||||||
|
error("%s: not found", iface->name);
|
||||||
|
|
||||||
|
/* Register the interface... */
|
||||||
|
if_register_receive(iface);
|
||||||
|
if_register_send(iface);
|
||||||
|
add_protocol(iface->name, iface->rfdesc, got_one, iface);
|
||||||
|
freeifaddrs(ifap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reinitialize_interfaces(void)
|
||||||
|
{
|
||||||
|
interfaces_invalidated = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for packets to come in using poll(). When a packet comes in,
|
||||||
|
* call receive_packet to receive the packet and possibly strip hardware
|
||||||
|
* addressing information from it, and then call through the
|
||||||
|
* bootp_packet_handler hook to try to do something with it.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dispatch(void)
|
||||||
|
{
|
||||||
|
int count, i, to_msec, nfds = 0;
|
||||||
|
struct protocol *l;
|
||||||
|
struct pollfd *fds;
|
||||||
|
time_t howlong;
|
||||||
|
|
||||||
|
for (l = protocols; l; l = l->next)
|
||||||
|
nfds++;
|
||||||
|
|
||||||
|
fds = malloc(nfds * sizeof(struct pollfd));
|
||||||
|
if (fds == NULL)
|
||||||
|
error("Can't allocate poll structures.");
|
||||||
|
|
||||||
|
do {
|
||||||
|
/*
|
||||||
|
* Call any expired timeouts, and then if there's still
|
||||||
|
* a timeout registered, time out the select call then.
|
||||||
|
*/
|
||||||
|
another:
|
||||||
|
if (timeouts) {
|
||||||
|
struct timeout *t;
|
||||||
|
|
||||||
|
if (timeouts->when <= cur_time) {
|
||||||
|
t = timeouts;
|
||||||
|
timeouts = timeouts->next;
|
||||||
|
(*(t->func))(t->what);
|
||||||
|
t->next = free_timeouts;
|
||||||
|
free_timeouts = t;
|
||||||
|
goto another;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Figure timeout in milliseconds, and check for
|
||||||
|
* potential overflow, so we can cram into an
|
||||||
|
* int for poll, while not polling with a
|
||||||
|
* negative timeout and blocking indefinitely.
|
||||||
|
*/
|
||||||
|
howlong = timeouts->when - cur_time;
|
||||||
|
if (howlong > INT_MAX / 1000)
|
||||||
|
howlong = INT_MAX / 1000;
|
||||||
|
to_msec = howlong * 1000;
|
||||||
|
} else
|
||||||
|
to_msec = -1;
|
||||||
|
|
||||||
|
/* Set up the descriptors to be polled. */
|
||||||
|
for (i = 0, l = protocols; l; l = l->next) {
|
||||||
|
struct interface_info *ip = l->local;
|
||||||
|
|
||||||
|
if (ip && (l->handler != got_one || !ip->dead)) {
|
||||||
|
fds[i].fd = l->fd;
|
||||||
|
fds[i].events = POLLIN;
|
||||||
|
fds[i].revents = 0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
error("No live interfaces to poll on - exiting.");
|
||||||
|
|
||||||
|
/* Wait for a packet or a timeout... XXX */
|
||||||
|
count = poll(fds, nfds, to_msec);
|
||||||
|
|
||||||
|
/* Not likely to be transitory... */
|
||||||
|
if (count == -1) {
|
||||||
|
if (errno == EAGAIN || errno == EINTR) {
|
||||||
|
time(&cur_time);
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
error("poll: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the current time... */
|
||||||
|
time(&cur_time);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (l = protocols; l; l = l->next) {
|
||||||
|
struct interface_info *ip;
|
||||||
|
ip = l->local;
|
||||||
|
if ((fds[i].revents & (POLLIN | POLLHUP))) {
|
||||||
|
fds[i].revents = 0;
|
||||||
|
if (ip && (l->handler != got_one ||
|
||||||
|
!ip->dead))
|
||||||
|
(*(l->handler))(l);
|
||||||
|
if (interfaces_invalidated)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
interfaces_invalidated = 0;
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
got_one(struct protocol *l)
|
||||||
|
{
|
||||||
|
struct sockaddr_in from;
|
||||||
|
struct hardware hfrom;
|
||||||
|
struct iaddr ifrom;
|
||||||
|
ssize_t result;
|
||||||
|
union {
|
||||||
|
/*
|
||||||
|
* Packet input buffer. Must be as large as largest
|
||||||
|
* possible MTU.
|
||||||
|
*/
|
||||||
|
unsigned char packbuf[4095];
|
||||||
|
struct dhcp_packet packet;
|
||||||
|
} u;
|
||||||
|
struct interface_info *ip = l->local;
|
||||||
|
|
||||||
|
if ((result = receive_packet(ip, u.packbuf, sizeof(u), &from,
|
||||||
|
&hfrom)) == -1) {
|
||||||
|
warning("receive_packet failed on %s: %s", ip->name,
|
||||||
|
strerror(errno));
|
||||||
|
ip->errors++;
|
||||||
|
if ((!interface_status(ip)) ||
|
||||||
|
(ip->noifmedia && ip->errors > 20)) {
|
||||||
|
/* our interface has gone away. */
|
||||||
|
warning("Interface %s no longer appears valid.",
|
||||||
|
ip->name);
|
||||||
|
ip->dead = 1;
|
||||||
|
interfaces_invalidated = 1;
|
||||||
|
close(l->fd);
|
||||||
|
remove_protocol(l);
|
||||||
|
free(ip);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (bootp_packet_handler) {
|
||||||
|
ifrom.len = 4;
|
||||||
|
memcpy(ifrom.iabuf, &from.sin_addr, ifrom.len);
|
||||||
|
|
||||||
|
(*bootp_packet_handler)(ip, &u.packet, result,
|
||||||
|
from.sin_port, ifrom, &hfrom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
interface_status(struct interface_info *ifinfo)
|
||||||
|
{
|
||||||
|
char *ifname = ifinfo->name;
|
||||||
|
int ifsock = ifinfo->rfdesc;
|
||||||
|
struct ifreq ifr;
|
||||||
|
struct ifmediareq ifmr;
|
||||||
|
|
||||||
|
/* get interface flags */
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||||
|
if (ioctl(ifsock, SIOCGIFFLAGS, &ifr) < 0) {
|
||||||
|
syslog(LOG_ERR, "ioctl(SIOCGIFFLAGS) on %s: %m", ifname);
|
||||||
|
goto inactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if one of UP and RUNNING flags is dropped,
|
||||||
|
* the interface is not active.
|
||||||
|
*/
|
||||||
|
if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
|
||||||
|
goto inactive;
|
||||||
|
|
||||||
|
/* Next, check carrier on the interface, if possible */
|
||||||
|
if (ifinfo->noifmedia)
|
||||||
|
goto active;
|
||||||
|
memset(&ifmr, 0, sizeof(ifmr));
|
||||||
|
strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
|
||||||
|
if (ioctl(ifsock, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
|
||||||
|
if (errno != EINVAL) {
|
||||||
|
syslog(LOG_DEBUG, "ioctl(SIOCGIFMEDIA) on %s: %m",
|
||||||
|
ifname);
|
||||||
|
|
||||||
|
ifinfo->noifmedia = 1;
|
||||||
|
goto active;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* EINVAL (or ENOTTY) simply means that the interface
|
||||||
|
* does not support the SIOCGIFMEDIA ioctl. We regard it alive.
|
||||||
|
*/
|
||||||
|
ifinfo->noifmedia = 1;
|
||||||
|
goto active;
|
||||||
|
}
|
||||||
|
if (ifmr.ifm_status & IFM_AVALID) {
|
||||||
|
switch (ifmr.ifm_active & IFM_NMASK) {
|
||||||
|
case IFM_ETHER:
|
||||||
|
if (ifmr.ifm_status & IFM_ACTIVE)
|
||||||
|
goto active;
|
||||||
|
else
|
||||||
|
goto inactive;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto inactive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inactive:
|
||||||
|
return (0);
|
||||||
|
active:
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
add_timeout(time_t when, void (*where)(void *), void *what)
|
||||||
|
{
|
||||||
|
struct timeout *t, *q;
|
||||||
|
|
||||||
|
/* See if this timeout supersedes an existing timeout. */
|
||||||
|
t = NULL;
|
||||||
|
for (q = timeouts; q; q = q->next) {
|
||||||
|
if (q->func == where && q->what == what) {
|
||||||
|
if (t)
|
||||||
|
t->next = q->next;
|
||||||
|
else
|
||||||
|
timeouts = q->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we didn't supersede a timeout, allocate a timeout
|
||||||
|
structure now. */
|
||||||
|
if (!q) {
|
||||||
|
if (free_timeouts) {
|
||||||
|
q = free_timeouts;
|
||||||
|
free_timeouts = q->next;
|
||||||
|
q->func = where;
|
||||||
|
q->what = what;
|
||||||
|
} else {
|
||||||
|
q = malloc(sizeof(struct timeout));
|
||||||
|
if (!q)
|
||||||
|
error("Can't allocate timeout structure!");
|
||||||
|
q->func = where;
|
||||||
|
q->what = what;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q->when = when;
|
||||||
|
|
||||||
|
/* Now sort this timeout into the timeout list. */
|
||||||
|
|
||||||
|
/* Beginning of list? */
|
||||||
|
if (!timeouts || timeouts->when > q->when) {
|
||||||
|
q->next = timeouts;
|
||||||
|
timeouts = q;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Middle of list? */
|
||||||
|
for (t = timeouts; t->next; t = t->next) {
|
||||||
|
if (t->next->when > q->when) {
|
||||||
|
q->next = t->next;
|
||||||
|
t->next = q;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End of list. */
|
||||||
|
t->next = q;
|
||||||
|
q->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cancel_timeout(void (*where)(void *), void *what)
|
||||||
|
{
|
||||||
|
struct timeout *t, *q;
|
||||||
|
|
||||||
|
/* Look for this timeout on the list, and unlink it if we find it. */
|
||||||
|
t = NULL;
|
||||||
|
for (q = timeouts; q; q = q->next) {
|
||||||
|
if (q->func == where && q->what == what) {
|
||||||
|
if (t)
|
||||||
|
t->next = q->next;
|
||||||
|
else
|
||||||
|
timeouts = q->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we found the timeout, put it on the free list. */
|
||||||
|
if (q) {
|
||||||
|
q->next = free_timeouts;
|
||||||
|
free_timeouts = q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a protocol to the list of protocols... */
|
||||||
|
void
|
||||||
|
add_protocol(char *name, int fd, void (*handler)(struct protocol *),
|
||||||
|
void *local)
|
||||||
|
{
|
||||||
|
struct protocol *p;
|
||||||
|
|
||||||
|
p = malloc(sizeof(*p));
|
||||||
|
if (!p)
|
||||||
|
error("can't allocate protocol struct for %s", name);
|
||||||
|
|
||||||
|
p->fd = fd;
|
||||||
|
p->handler = handler;
|
||||||
|
p->local = local;
|
||||||
|
p->next = protocols;
|
||||||
|
protocols = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
remove_protocol(struct protocol *proto)
|
||||||
|
{
|
||||||
|
struct protocol *p, *next, *prev;
|
||||||
|
|
||||||
|
prev = NULL;
|
||||||
|
for (p = protocols; p; p = next) {
|
||||||
|
next = p->next;
|
||||||
|
if (p == proto) {
|
||||||
|
if (prev)
|
||||||
|
prev->next = p->next;
|
||||||
|
else
|
||||||
|
protocols = p->next;
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
interface_link_status(char *ifname)
|
||||||
|
{
|
||||||
|
struct ifmediareq ifmr;
|
||||||
|
int sock;
|
||||||
|
|
||||||
|
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||||
|
error("Can't create socket");
|
||||||
|
|
||||||
|
memset(&ifmr, 0, sizeof(ifmr));
|
||||||
|
strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
|
||||||
|
if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
|
||||||
|
/* EINVAL -> link state unknown. treat as active */
|
||||||
|
if (errno != EINVAL)
|
||||||
|
syslog(LOG_DEBUG, "ioctl(SIOCGIFMEDIA) on %s: %m",
|
||||||
|
ifname);
|
||||||
|
close(sock);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
close(sock);
|
||||||
|
|
||||||
|
if (ifmr.ifm_status & IFM_AVALID) {
|
||||||
|
if ((ifmr.ifm_active & IFM_NMASK) == IFM_ETHER) {
|
||||||
|
if (ifmr.ifm_status & IFM_ACTIVE)
|
||||||
|
return (1);
|
||||||
|
else
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
234
sbin/dhclient/errwarn.c
Normal file
234
sbin/dhclient/errwarn.c
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
/* $OpenBSD: errwarn.c,v 1.7 2004/05/04 22:23:01 mickey Exp $ */
|
||||||
|
|
||||||
|
/* Errors and warnings... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1996 The Internet Software Consortium.
|
||||||
|
* All Rights Reserved.
|
||||||
|
* Copyright (c) 1995 RadioMail Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of RadioMail Corporation, the Internet Software
|
||||||
|
* Consortium 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 RADIOMAIL CORPORATION, THE INTERNET
|
||||||
|
* SOFTWARE CONSORTIUM AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL RADIOMAIL CORPORATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software was written for RadioMail Corporation by Ted Lemon
|
||||||
|
* under a contract with Vixie Enterprises. Further modifications have
|
||||||
|
* been made for the Internet Software Consortium under a contract
|
||||||
|
* with Vixie Laboratories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
static void do_percentm(char *obuf, size_t size, char *ibuf);
|
||||||
|
|
||||||
|
static char mbuf[1024];
|
||||||
|
static char fbuf[1024];
|
||||||
|
|
||||||
|
int warnings_occurred;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log an error message, then exit.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
error(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
do_percentm(fbuf, sizeof(fbuf), fmt);
|
||||||
|
|
||||||
|
va_start(list, fmt);
|
||||||
|
vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
syslog(log_priority | LOG_ERR, "%s", mbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Also log it to stderr? */
|
||||||
|
if (log_perror) {
|
||||||
|
write(2, mbuf, strlen(mbuf));
|
||||||
|
write(2, "\n", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
syslog(LOG_CRIT, "exiting.");
|
||||||
|
if (log_perror) {
|
||||||
|
fprintf(stderr, "exiting.\n");
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log a warning message...
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
warning(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
do_percentm(fbuf, sizeof(fbuf), fmt);
|
||||||
|
|
||||||
|
va_start(list, fmt);
|
||||||
|
vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
syslog(log_priority | LOG_ERR, "%s", mbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (log_perror) {
|
||||||
|
write(2, mbuf, strlen(mbuf));
|
||||||
|
write(2, "\n", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log a note...
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
note(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
do_percentm(fbuf, sizeof(fbuf), fmt);
|
||||||
|
|
||||||
|
va_start(list, fmt);
|
||||||
|
vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
syslog(log_priority | LOG_INFO, "%s", mbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (log_perror) {
|
||||||
|
write(2, mbuf, strlen(mbuf));
|
||||||
|
write(2, "\n", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log a debug message...
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
debug(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
do_percentm(fbuf, sizeof(fbuf), fmt);
|
||||||
|
|
||||||
|
va_start(list, fmt);
|
||||||
|
vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
syslog(log_priority | LOG_DEBUG, "%s", mbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (log_perror) {
|
||||||
|
write(2, mbuf, strlen(mbuf));
|
||||||
|
write(2, "\n", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find %m in the input string and substitute an error message string.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
do_percentm(char *obuf, size_t size, char *ibuf)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
char *s = ibuf;
|
||||||
|
char *t = obuf;
|
||||||
|
size_t prlen;
|
||||||
|
size_t fmt_left;
|
||||||
|
int saved_errno = errno;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We wouldn't need this mess if printf handled %m, or if
|
||||||
|
* strerror() had been invented before syslog().
|
||||||
|
*/
|
||||||
|
for (fmt_left = size; (ch = *s); ++s) {
|
||||||
|
if (ch == '%' && s[1] == 'm') {
|
||||||
|
++s;
|
||||||
|
prlen = snprintf(t, fmt_left, "%s",
|
||||||
|
strerror(saved_errno));
|
||||||
|
if (prlen >= fmt_left)
|
||||||
|
prlen = fmt_left - 1;
|
||||||
|
t += prlen;
|
||||||
|
fmt_left -= prlen;
|
||||||
|
} else {
|
||||||
|
if (fmt_left > 1) {
|
||||||
|
*t++ = ch;
|
||||||
|
fmt_left--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*t = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parse_warn(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list list;
|
||||||
|
static char spaces[] =
|
||||||
|
" "
|
||||||
|
" "; /* 80 spaces */
|
||||||
|
|
||||||
|
do_percentm(mbuf, sizeof(mbuf), fmt);
|
||||||
|
snprintf(fbuf, sizeof(fbuf), "%s line %d: %s", tlname, lexline, mbuf);
|
||||||
|
va_start(list, fmt);
|
||||||
|
vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
syslog(log_priority | LOG_ERR, "%s", mbuf);
|
||||||
|
syslog(log_priority | LOG_ERR, "%s", token_line);
|
||||||
|
if (lexline < 81)
|
||||||
|
syslog(log_priority | LOG_ERR,
|
||||||
|
"%s^", &spaces[sizeof(spaces) - lexchar]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (log_perror) {
|
||||||
|
write(2, mbuf, strlen(mbuf));
|
||||||
|
write(2, "\n", 1);
|
||||||
|
write(2, token_line, strlen(token_line));
|
||||||
|
write(2, "\n", 1);
|
||||||
|
write(2, spaces, lexchar - 1);
|
||||||
|
write(2, "^\n", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
warnings_occurred = 1;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
119
sbin/dhclient/hash.c
Normal file
119
sbin/dhclient/hash.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/* $OpenBSD: hash.c,v 1.9 2004/05/10 15:30:47 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Routines for manipulating hash tables... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
static int do_hash(unsigned char *, int, int);
|
||||||
|
|
||||||
|
struct hash_table *
|
||||||
|
new_hash(void)
|
||||||
|
{
|
||||||
|
struct hash_table *rv = new_hash_table(DEFAULT_HASH_SIZE);
|
||||||
|
|
||||||
|
if (!rv)
|
||||||
|
return (rv);
|
||||||
|
memset(&rv->buckets[0], 0,
|
||||||
|
DEFAULT_HASH_SIZE * sizeof(struct hash_bucket *));
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_hash(unsigned char *name, int len, int size)
|
||||||
|
{
|
||||||
|
unsigned char *s = name;
|
||||||
|
int accum = 0, i = len;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
/* Add the character in... */
|
||||||
|
accum += *s++;
|
||||||
|
/* Add carry back in... */
|
||||||
|
while (accum > 255)
|
||||||
|
accum = (accum & 255) + (accum >> 8);
|
||||||
|
}
|
||||||
|
return (accum % size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_hash(struct hash_table *table, unsigned char *name, int len,
|
||||||
|
unsigned char *pointer)
|
||||||
|
{
|
||||||
|
struct hash_bucket *bp;
|
||||||
|
int hashno;
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
return;
|
||||||
|
if (!len)
|
||||||
|
len = strlen((char *)name);
|
||||||
|
|
||||||
|
hashno = do_hash(name, len, table->hash_count);
|
||||||
|
bp = new_hash_bucket();
|
||||||
|
|
||||||
|
if (!bp) {
|
||||||
|
warning("Can't add %s to hash table.", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bp->name = name;
|
||||||
|
bp->value = pointer;
|
||||||
|
bp->next = table->buckets[hashno];
|
||||||
|
bp->len = len;
|
||||||
|
table->buckets[hashno] = bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *
|
||||||
|
hash_lookup(struct hash_table *table, unsigned char *name, int len)
|
||||||
|
{
|
||||||
|
struct hash_bucket *bp;
|
||||||
|
int hashno;
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
len = strlen((char *)name);
|
||||||
|
|
||||||
|
hashno = do_hash(name, len, table->hash_count);
|
||||||
|
|
||||||
|
for (bp = table->buckets[hashno]; bp; bp = bp->next)
|
||||||
|
if (len == bp->len && !memcmp(bp->name, name, len))
|
||||||
|
return (bp->value);
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
118
sbin/dhclient/inet.c
Normal file
118
sbin/dhclient/inet.c
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/* $OpenBSD: inet.c,v 1.7 2004/05/04 21:48:16 deraadt Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Subroutines to manipulate internet addresses in a safely portable
|
||||||
|
* way...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1996 The Internet Software Consortium. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return just the network number of an internet address...
|
||||||
|
*/
|
||||||
|
struct iaddr
|
||||||
|
subnet_number(struct iaddr addr, struct iaddr mask)
|
||||||
|
{
|
||||||
|
struct iaddr rv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
rv.len = 0;
|
||||||
|
|
||||||
|
/* Both addresses must have the same length... */
|
||||||
|
if (addr.len != mask.len)
|
||||||
|
return (rv);
|
||||||
|
|
||||||
|
rv.len = addr.len;
|
||||||
|
for (i = 0; i < rv.len; i++)
|
||||||
|
rv.iabuf[i] = addr.iabuf[i] & mask.iabuf[i];
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a subnet number and netmask, return the address on that subnet
|
||||||
|
* for which the host portion of the address is all ones (the standard
|
||||||
|
* broadcast address).
|
||||||
|
*/
|
||||||
|
struct iaddr
|
||||||
|
broadcast_addr(struct iaddr subnet, struct iaddr mask)
|
||||||
|
{
|
||||||
|
struct iaddr rv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (subnet.len != mask.len) {
|
||||||
|
rv.len = 0;
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < subnet.len; i++)
|
||||||
|
rv.iabuf[i] = subnet.iabuf[i] | (~mask.iabuf[i] & 255);
|
||||||
|
rv.len = subnet.len;
|
||||||
|
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
addr_eq(struct iaddr addr1, struct iaddr addr2)
|
||||||
|
{
|
||||||
|
if (addr1.len != addr2.len)
|
||||||
|
return (0);
|
||||||
|
return (memcmp(addr1.iabuf, addr2.iabuf, addr1.len) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
piaddr(struct iaddr addr)
|
||||||
|
{
|
||||||
|
static char pbuf[32];
|
||||||
|
struct in_addr a;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
memcpy(&a, &(addr.iabuf), sizeof(struct in_addr));
|
||||||
|
|
||||||
|
if (addr.len == 0)
|
||||||
|
strlcpy(pbuf, "<null address>", sizeof(pbuf));
|
||||||
|
else {
|
||||||
|
s = inet_ntoa(a);
|
||||||
|
if (s != NULL)
|
||||||
|
strlcpy(pbuf, s, sizeof(pbuf));
|
||||||
|
else
|
||||||
|
strlcpy(pbuf, "<invalid address>", sizeof(pbuf));
|
||||||
|
}
|
||||||
|
return (pbuf);
|
||||||
|
}
|
717
sbin/dhclient/options.c
Normal file
717
sbin/dhclient/options.c
Normal file
@ -0,0 +1,717 @@
|
|||||||
|
/* $OpenBSD: options.c,v 1.15 2004/12/26 03:17:07 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* DHCP options parsing and reassembly. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define DHCP_OPTION_DATA
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
int bad_options = 0;
|
||||||
|
int bad_options_max = 5;
|
||||||
|
|
||||||
|
void parse_options(struct packet *);
|
||||||
|
void parse_option_buffer(struct packet *, unsigned char *, int);
|
||||||
|
int store_options(unsigned char *, int, struct tree_cache **,
|
||||||
|
unsigned char *, int, int, int, int);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse all available options out of the specified packet.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse_options(struct packet *packet)
|
||||||
|
{
|
||||||
|
/* Initially, zero all option pointers. */
|
||||||
|
memset(packet->options, 0, sizeof(packet->options));
|
||||||
|
|
||||||
|
/* If we don't see the magic cookie, there's nothing to parse. */
|
||||||
|
if (memcmp(packet->raw->options, DHCP_OPTIONS_COOKIE, 4)) {
|
||||||
|
packet->options_valid = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Go through the options field, up to the end of the packet or
|
||||||
|
* the End field.
|
||||||
|
*/
|
||||||
|
parse_option_buffer(packet, &packet->raw->options[4],
|
||||||
|
packet->packet_length - DHCP_FIXED_NON_UDP - 4);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we parsed a DHCP Option Overload option, parse more
|
||||||
|
* options out of the buffer(s) containing them.
|
||||||
|
*/
|
||||||
|
if (packet->options_valid &&
|
||||||
|
packet->options[DHO_DHCP_OPTION_OVERLOAD].data) {
|
||||||
|
if (packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)
|
||||||
|
parse_option_buffer(packet,
|
||||||
|
(unsigned char *)packet->raw->file,
|
||||||
|
sizeof(packet->raw->file));
|
||||||
|
if (packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)
|
||||||
|
parse_option_buffer(packet,
|
||||||
|
(unsigned char *)packet->raw->sname,
|
||||||
|
sizeof(packet->raw->sname));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse options out of the specified buffer, storing addresses of
|
||||||
|
* option values in packet->options and setting packet->options_valid if
|
||||||
|
* no errors are encountered.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse_option_buffer(struct packet *packet,
|
||||||
|
unsigned char *buffer, int length)
|
||||||
|
{
|
||||||
|
unsigned char *s, *t, *end = buffer + length;
|
||||||
|
int len, code;
|
||||||
|
|
||||||
|
for (s = buffer; *s != DHO_END && s < end; ) {
|
||||||
|
code = s[0];
|
||||||
|
|
||||||
|
/* Pad options don't have a length - just skip them. */
|
||||||
|
if (code == DHO_PAD) {
|
||||||
|
s++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (s + 2 > end) {
|
||||||
|
len = 65536;
|
||||||
|
goto bogus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All other fields (except end, see above) have a
|
||||||
|
* one-byte length.
|
||||||
|
*/
|
||||||
|
len = s[1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the length is outrageous, silently skip the rest,
|
||||||
|
* and mark the packet bad. Unfortunately some crappy
|
||||||
|
* dhcp servers always seem to give us garbage on the
|
||||||
|
* end of a packet. so rather than keep refusing, give
|
||||||
|
* up and try to take one after seeing a few without
|
||||||
|
* anything good.
|
||||||
|
*/
|
||||||
|
if (s + len + 2 > end) {
|
||||||
|
bogus:
|
||||||
|
bad_options++;
|
||||||
|
warning("option %s (%d) %s.",
|
||||||
|
dhcp_options[code].name, len,
|
||||||
|
"larger than buffer");
|
||||||
|
if (bad_options == bad_options_max) {
|
||||||
|
packet->options_valid = 1;
|
||||||
|
bad_options = 0;
|
||||||
|
warning("Many bogus options seen in offers. "
|
||||||
|
"Taking this offer in spite of bogus "
|
||||||
|
"options - hope for the best!");
|
||||||
|
} else {
|
||||||
|
warning("rejecting bogus offer.");
|
||||||
|
packet->options_valid = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If we haven't seen this option before, just make
|
||||||
|
* space for it and copy it there.
|
||||||
|
*/
|
||||||
|
if (!packet->options[code].data) {
|
||||||
|
if (!(t = calloc(1, len + 1)))
|
||||||
|
error("Can't allocate storage for option %s.",
|
||||||
|
dhcp_options[code].name);
|
||||||
|
/*
|
||||||
|
* Copy and NUL-terminate the option (in case
|
||||||
|
* it's an ASCII string.
|
||||||
|
*/
|
||||||
|
memcpy(t, &s[2], len);
|
||||||
|
t[len] = 0;
|
||||||
|
packet->options[code].len = len;
|
||||||
|
packet->options[code].data = t;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If it's a repeat, concatenate it to whatever
|
||||||
|
* we last saw. This is really only required
|
||||||
|
* for clients, but what the heck...
|
||||||
|
*/
|
||||||
|
t = calloc(1, len + packet->options[code].len + 1);
|
||||||
|
if (!t)
|
||||||
|
error("Can't expand storage for option %s.",
|
||||||
|
dhcp_options[code].name);
|
||||||
|
memcpy(t, packet->options[code].data,
|
||||||
|
packet->options[code].len);
|
||||||
|
memcpy(t + packet->options[code].len,
|
||||||
|
&s[2], len);
|
||||||
|
packet->options[code].len += len;
|
||||||
|
t[packet->options[code].len] = 0;
|
||||||
|
free(packet->options[code].data);
|
||||||
|
packet->options[code].data = t;
|
||||||
|
}
|
||||||
|
s += len + 2;
|
||||||
|
}
|
||||||
|
packet->options_valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cons options into a big buffer, and then split them out into the
|
||||||
|
* three separate buffers if needed. This allows us to cons up a set of
|
||||||
|
* vendor options using the same routine.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
|
||||||
|
int mms, struct tree_cache **options,
|
||||||
|
int overload, /* Overload flags that may be set. */
|
||||||
|
int terminate, int bootpp, u_int8_t *prl, int prl_len)
|
||||||
|
{
|
||||||
|
unsigned char priority_list[300], buffer[4096];
|
||||||
|
int priority_len, main_buffer_size, mainbufix, bufix;
|
||||||
|
int option_size, length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the client has provided a maximum DHCP message size, use
|
||||||
|
* that; otherwise, if it's BOOTP, only 64 bytes; otherwise use
|
||||||
|
* up to the minimum IP MTU size (576 bytes).
|
||||||
|
*
|
||||||
|
* XXX if a BOOTP client specifies a max message size, we will
|
||||||
|
* honor it.
|
||||||
|
*/
|
||||||
|
if (!mms &&
|
||||||
|
inpacket &&
|
||||||
|
inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data &&
|
||||||
|
(inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].len >=
|
||||||
|
sizeof(u_int16_t)))
|
||||||
|
mms = getUShort(
|
||||||
|
inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data);
|
||||||
|
|
||||||
|
if (mms)
|
||||||
|
main_buffer_size = mms - DHCP_FIXED_LEN;
|
||||||
|
else if (bootpp)
|
||||||
|
main_buffer_size = 64;
|
||||||
|
else
|
||||||
|
main_buffer_size = 576 - DHCP_FIXED_LEN;
|
||||||
|
|
||||||
|
if (main_buffer_size > sizeof(buffer))
|
||||||
|
main_buffer_size = sizeof(buffer);
|
||||||
|
|
||||||
|
/* Preload the option priority list with mandatory options. */
|
||||||
|
priority_len = 0;
|
||||||
|
priority_list[priority_len++] = DHO_DHCP_MESSAGE_TYPE;
|
||||||
|
priority_list[priority_len++] = DHO_DHCP_SERVER_IDENTIFIER;
|
||||||
|
priority_list[priority_len++] = DHO_DHCP_LEASE_TIME;
|
||||||
|
priority_list[priority_len++] = DHO_DHCP_MESSAGE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the client has provided a list of options that it wishes
|
||||||
|
* returned, use it to prioritize. Otherwise, prioritize based
|
||||||
|
* on the default priority list.
|
||||||
|
*/
|
||||||
|
if (inpacket &&
|
||||||
|
inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
|
||||||
|
int prlen =
|
||||||
|
inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].len;
|
||||||
|
if (prlen + priority_len > sizeof(priority_list))
|
||||||
|
prlen = sizeof(priority_list) - priority_len;
|
||||||
|
|
||||||
|
memcpy(&priority_list[priority_len],
|
||||||
|
inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data,
|
||||||
|
prlen);
|
||||||
|
priority_len += prlen;
|
||||||
|
prl = priority_list;
|
||||||
|
} else if (prl) {
|
||||||
|
if (prl_len + priority_len > sizeof(priority_list))
|
||||||
|
prl_len = sizeof(priority_list) - priority_len;
|
||||||
|
|
||||||
|
memcpy(&priority_list[priority_len], prl, prl_len);
|
||||||
|
priority_len += prl_len;
|
||||||
|
prl = priority_list;
|
||||||
|
} else {
|
||||||
|
memcpy(&priority_list[priority_len],
|
||||||
|
dhcp_option_default_priority_list,
|
||||||
|
sizeof_dhcp_option_default_priority_list);
|
||||||
|
priority_len += sizeof_dhcp_option_default_priority_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the options into the big buffer... */
|
||||||
|
option_size = store_options(
|
||||||
|
buffer,
|
||||||
|
(main_buffer_size - 7 + ((overload & 1) ? DHCP_FILE_LEN : 0) +
|
||||||
|
((overload & 2) ? DHCP_SNAME_LEN : 0)),
|
||||||
|
options, priority_list, priority_len, main_buffer_size,
|
||||||
|
(main_buffer_size + ((overload & 1) ? DHCP_FILE_LEN : 0)),
|
||||||
|
terminate);
|
||||||
|
|
||||||
|
/* Put the cookie up front... */
|
||||||
|
memcpy(outpacket->options, DHCP_OPTIONS_COOKIE, 4);
|
||||||
|
mainbufix = 4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're going to have to overload, store the overload option
|
||||||
|
* at the beginning. If we can, though, just store the whole
|
||||||
|
* thing in the packet's option buffer and leave it at that.
|
||||||
|
*/
|
||||||
|
if (option_size <= main_buffer_size - mainbufix) {
|
||||||
|
memcpy(&outpacket->options[mainbufix],
|
||||||
|
buffer, option_size);
|
||||||
|
mainbufix += option_size;
|
||||||
|
if (mainbufix < main_buffer_size)
|
||||||
|
outpacket->options[mainbufix++] = DHO_END;
|
||||||
|
length = DHCP_FIXED_NON_UDP + mainbufix;
|
||||||
|
} else {
|
||||||
|
outpacket->options[mainbufix++] = DHO_DHCP_OPTION_OVERLOAD;
|
||||||
|
outpacket->options[mainbufix++] = 1;
|
||||||
|
if (option_size >
|
||||||
|
main_buffer_size - mainbufix + DHCP_FILE_LEN)
|
||||||
|
outpacket->options[mainbufix++] = 3;
|
||||||
|
else
|
||||||
|
outpacket->options[mainbufix++] = 1;
|
||||||
|
|
||||||
|
memcpy(&outpacket->options[mainbufix],
|
||||||
|
buffer, main_buffer_size - mainbufix);
|
||||||
|
bufix = main_buffer_size - mainbufix;
|
||||||
|
length = DHCP_FIXED_NON_UDP + mainbufix;
|
||||||
|
if (overload & 1) {
|
||||||
|
if (option_size - bufix <= DHCP_FILE_LEN) {
|
||||||
|
memcpy(outpacket->file,
|
||||||
|
&buffer[bufix], option_size - bufix);
|
||||||
|
mainbufix = option_size - bufix;
|
||||||
|
if (mainbufix < DHCP_FILE_LEN)
|
||||||
|
outpacket->file[mainbufix++] = (char)DHO_END;
|
||||||
|
while (mainbufix < DHCP_FILE_LEN)
|
||||||
|
outpacket->file[mainbufix++] = (char)DHO_PAD;
|
||||||
|
} else {
|
||||||
|
memcpy(outpacket->file,
|
||||||
|
&buffer[bufix], DHCP_FILE_LEN);
|
||||||
|
bufix += DHCP_FILE_LEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((overload & 2) && option_size < bufix) {
|
||||||
|
memcpy(outpacket->sname,
|
||||||
|
&buffer[bufix], option_size - bufix);
|
||||||
|
|
||||||
|
mainbufix = option_size - bufix;
|
||||||
|
if (mainbufix < DHCP_SNAME_LEN)
|
||||||
|
outpacket->file[mainbufix++] = (char)DHO_END;
|
||||||
|
while (mainbufix < DHCP_SNAME_LEN)
|
||||||
|
outpacket->file[mainbufix++] = (char)DHO_PAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Store all the requested options into the requested buffer.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
store_options(unsigned char *buffer, int buflen, struct tree_cache **options,
|
||||||
|
unsigned char *priority_list, int priority_len, int first_cutoff,
|
||||||
|
int second_cutoff, int terminate)
|
||||||
|
{
|
||||||
|
int bufix = 0, option_stored[256], i, ix, tto;
|
||||||
|
|
||||||
|
/* Zero out the stored-lengths array. */
|
||||||
|
memset(option_stored, 0, sizeof(option_stored));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy out the options in the order that they appear in the
|
||||||
|
* priority list...
|
||||||
|
*/
|
||||||
|
for (i = 0; i < priority_len; i++) {
|
||||||
|
/* Code for next option to try to store. */
|
||||||
|
int code = priority_list[i];
|
||||||
|
int optstart;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of bytes left to store (some may already have
|
||||||
|
* been stored by a previous pass).
|
||||||
|
*/
|
||||||
|
int length;
|
||||||
|
|
||||||
|
/* If no data is available for this option, skip it. */
|
||||||
|
if (!options[code]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The client could ask for things that are mandatory,
|
||||||
|
* in which case we should avoid storing them twice...
|
||||||
|
*/
|
||||||
|
if (option_stored[code])
|
||||||
|
continue;
|
||||||
|
option_stored[code] = 1;
|
||||||
|
|
||||||
|
/* We should now have a constant length for the option. */
|
||||||
|
length = options[code]->len;
|
||||||
|
|
||||||
|
/* Do we add a NUL? */
|
||||||
|
if (terminate && dhcp_options[code].format[0] == 't') {
|
||||||
|
length++;
|
||||||
|
tto = 1;
|
||||||
|
} else
|
||||||
|
tto = 0;
|
||||||
|
|
||||||
|
/* Try to store the option. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the option's length is more than 255, we must
|
||||||
|
* store it in multiple hunks. Store 255-byte hunks
|
||||||
|
* first. However, in any case, if the option data will
|
||||||
|
* cross a buffer boundary, split it across that
|
||||||
|
* boundary.
|
||||||
|
*/
|
||||||
|
ix = 0;
|
||||||
|
|
||||||
|
optstart = bufix;
|
||||||
|
while (length) {
|
||||||
|
unsigned char incr = length > 255 ? 255 : length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this hunk of the buffer will cross a
|
||||||
|
* boundary, only go up to the boundary in this
|
||||||
|
* pass.
|
||||||
|
*/
|
||||||
|
if (bufix < first_cutoff &&
|
||||||
|
bufix + incr > first_cutoff)
|
||||||
|
incr = first_cutoff - bufix;
|
||||||
|
else if (bufix < second_cutoff &&
|
||||||
|
bufix + incr > second_cutoff)
|
||||||
|
incr = second_cutoff - bufix;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this option is going to overflow the
|
||||||
|
* buffer, skip it.
|
||||||
|
*/
|
||||||
|
if (bufix + 2 + incr > buflen) {
|
||||||
|
bufix = optstart;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Everything looks good - copy it in! */
|
||||||
|
buffer[bufix] = code;
|
||||||
|
buffer[bufix + 1] = incr;
|
||||||
|
if (tto && incr == length) {
|
||||||
|
memcpy(buffer + bufix + 2,
|
||||||
|
options[code]->value + ix, incr - 1);
|
||||||
|
buffer[bufix + 2 + incr - 1] = 0;
|
||||||
|
} else
|
||||||
|
memcpy(buffer + bufix + 2,
|
||||||
|
options[code]->value + ix, incr);
|
||||||
|
length -= incr;
|
||||||
|
ix += incr;
|
||||||
|
bufix += 2 + incr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (bufix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format the specified option so that a human can easily read it.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
pretty_print_option(unsigned int code, unsigned char *data, int len,
|
||||||
|
int emit_commas, int emit_quotes)
|
||||||
|
{
|
||||||
|
static char optbuf[32768]; /* XXX */
|
||||||
|
int hunksize = 0, numhunk = -1, numelem = 0;
|
||||||
|
char fmtbuf[32], *op = optbuf;
|
||||||
|
int i, j, k, opleft = sizeof(optbuf);
|
||||||
|
unsigned char *dp = data;
|
||||||
|
struct in_addr foo;
|
||||||
|
char comma;
|
||||||
|
|
||||||
|
/* Code should be between 0 and 255. */
|
||||||
|
if (code > 255)
|
||||||
|
error("pretty_print_option: bad code %d", code);
|
||||||
|
|
||||||
|
if (emit_commas)
|
||||||
|
comma = ',';
|
||||||
|
else
|
||||||
|
comma = ' ';
|
||||||
|
|
||||||
|
/* Figure out the size of the data. */
|
||||||
|
for (i = 0; dhcp_options[code].format[i]; i++) {
|
||||||
|
if (!numhunk) {
|
||||||
|
warning("%s: Excess information in format string: %s",
|
||||||
|
dhcp_options[code].name,
|
||||||
|
&(dhcp_options[code].format[i]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
numelem++;
|
||||||
|
fmtbuf[i] = dhcp_options[code].format[i];
|
||||||
|
switch (dhcp_options[code].format[i]) {
|
||||||
|
case 'A':
|
||||||
|
--numelem;
|
||||||
|
fmtbuf[i] = 0;
|
||||||
|
numhunk = 0;
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
for (k = 0; k < len; k++)
|
||||||
|
if (!isascii(data[k]) ||
|
||||||
|
!isprint(data[k]))
|
||||||
|
break;
|
||||||
|
if (k == len) {
|
||||||
|
fmtbuf[i] = 't';
|
||||||
|
numhunk = -2;
|
||||||
|
} else {
|
||||||
|
fmtbuf[i] = 'x';
|
||||||
|
hunksize++;
|
||||||
|
comma = ':';
|
||||||
|
numhunk = 0;
|
||||||
|
}
|
||||||
|
fmtbuf[i + 1] = 0;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
fmtbuf[i] = 't';
|
||||||
|
fmtbuf[i + 1] = 0;
|
||||||
|
numhunk = -2;
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
case 'l':
|
||||||
|
case 'L':
|
||||||
|
hunksize += 4;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
hunksize += 2;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
case 'f':
|
||||||
|
hunksize++;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warning("%s: garbage in format string: %s",
|
||||||
|
dhcp_options[code].name,
|
||||||
|
&(dhcp_options[code].format[i]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for too few bytes... */
|
||||||
|
if (hunksize > len) {
|
||||||
|
warning("%s: expecting at least %d bytes; got %d",
|
||||||
|
dhcp_options[code].name, hunksize, len);
|
||||||
|
return ("<error>");
|
||||||
|
}
|
||||||
|
/* Check for too many bytes... */
|
||||||
|
if (numhunk == -1 && hunksize < len)
|
||||||
|
warning("%s: %d extra bytes",
|
||||||
|
dhcp_options[code].name, len - hunksize);
|
||||||
|
|
||||||
|
/* If this is an array, compute its size. */
|
||||||
|
if (!numhunk)
|
||||||
|
numhunk = len / hunksize;
|
||||||
|
/* See if we got an exact number of hunks. */
|
||||||
|
if (numhunk > 0 && numhunk * hunksize < len)
|
||||||
|
warning("%s: %d extra bytes at end of array",
|
||||||
|
dhcp_options[code].name, len - numhunk * hunksize);
|
||||||
|
|
||||||
|
/* A one-hunk array prints the same as a single hunk. */
|
||||||
|
if (numhunk < 0)
|
||||||
|
numhunk = 1;
|
||||||
|
|
||||||
|
/* Cycle through the array (or hunk) printing the data. */
|
||||||
|
for (i = 0; i < numhunk; i++) {
|
||||||
|
for (j = 0; j < numelem; j++) {
|
||||||
|
int opcount;
|
||||||
|
switch (fmtbuf[j]) {
|
||||||
|
case 't':
|
||||||
|
if (emit_quotes) {
|
||||||
|
*op++ = '"';
|
||||||
|
opleft--;
|
||||||
|
}
|
||||||
|
for (; dp < data + len; dp++) {
|
||||||
|
if (!isascii(*dp) ||
|
||||||
|
!isprint(*dp)) {
|
||||||
|
if (dp + 1 != data + len ||
|
||||||
|
*dp != 0) {
|
||||||
|
snprintf(op, opleft,
|
||||||
|
"\\%03o", *dp);
|
||||||
|
op += 4;
|
||||||
|
opleft -= 4;
|
||||||
|
}
|
||||||
|
} else if (*dp == '"' ||
|
||||||
|
*dp == '\'' ||
|
||||||
|
*dp == '$' ||
|
||||||
|
*dp == '`' ||
|
||||||
|
*dp == '\\') {
|
||||||
|
*op++ = '\\';
|
||||||
|
*op++ = *dp;
|
||||||
|
opleft -= 2;
|
||||||
|
} else {
|
||||||
|
*op++ = *dp;
|
||||||
|
opleft--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (emit_quotes) {
|
||||||
|
*op++ = '"';
|
||||||
|
opleft--;
|
||||||
|
}
|
||||||
|
|
||||||
|
*op = 0;
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
foo.s_addr = htonl(getULong(dp));
|
||||||
|
opcount = strlcpy(op, inet_ntoa(foo), opleft);
|
||||||
|
if (opcount >= opleft)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
dp += 4;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
opcount = snprintf(op, opleft, "%ld",
|
||||||
|
(long)getLong(dp));
|
||||||
|
if (opcount >= opleft || opcount == -1)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
dp += 4;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
opcount = snprintf(op, opleft, "%ld",
|
||||||
|
(unsigned long)getULong(dp));
|
||||||
|
if (opcount >= opleft || opcount == -1)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
dp += 4;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
opcount = snprintf(op, opleft, "%d",
|
||||||
|
getShort(dp));
|
||||||
|
if (opcount >= opleft || opcount == -1)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
dp += 2;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
opcount = snprintf(op, opleft, "%d",
|
||||||
|
getUShort(dp));
|
||||||
|
if (opcount >= opleft || opcount == -1)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
dp += 2;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
opcount = snprintf(op, opleft, "%d",
|
||||||
|
*(char *)dp++);
|
||||||
|
if (opcount >= opleft || opcount == -1)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
opcount = snprintf(op, opleft, "%d", *dp++);
|
||||||
|
if (opcount >= opleft || opcount == -1)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
opcount = snprintf(op, opleft, "%x", *dp++);
|
||||||
|
if (opcount >= opleft || opcount == -1)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
opcount = strlcpy(op,
|
||||||
|
*dp++ ? "true" : "false", opleft);
|
||||||
|
if (opcount >= opleft)
|
||||||
|
goto toobig;
|
||||||
|
opleft -= opcount;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warning("Unexpected format code %c", fmtbuf[j]);
|
||||||
|
}
|
||||||
|
op += strlen(op);
|
||||||
|
opleft -= strlen(op);
|
||||||
|
if (opleft < 1)
|
||||||
|
goto toobig;
|
||||||
|
if (j + 1 < numelem && comma != ':') {
|
||||||
|
*op++ = ' ';
|
||||||
|
opleft--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i + 1 < numhunk) {
|
||||||
|
*op++ = comma;
|
||||||
|
opleft--;
|
||||||
|
}
|
||||||
|
if (opleft < 1)
|
||||||
|
goto toobig;
|
||||||
|
|
||||||
|
}
|
||||||
|
return (optbuf);
|
||||||
|
toobig:
|
||||||
|
warning("dhcp option too large");
|
||||||
|
return ("<error>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
do_packet(struct interface_info *interface, struct dhcp_packet *packet,
|
||||||
|
int len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
|
||||||
|
{
|
||||||
|
struct packet tp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (packet->hlen > sizeof(packet->chaddr)) {
|
||||||
|
note("Discarding packet with invalid hlen.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&tp, 0, sizeof(tp));
|
||||||
|
tp.raw = packet;
|
||||||
|
tp.packet_length = len;
|
||||||
|
tp.client_port = from_port;
|
||||||
|
tp.client_addr = from;
|
||||||
|
tp.interface = interface;
|
||||||
|
tp.haddr = hfrom;
|
||||||
|
|
||||||
|
parse_options(&tp);
|
||||||
|
if (tp.options_valid &&
|
||||||
|
tp.options[DHO_DHCP_MESSAGE_TYPE].data)
|
||||||
|
tp.packet_type = tp.options[DHO_DHCP_MESSAGE_TYPE].data[0];
|
||||||
|
if (tp.packet_type)
|
||||||
|
dhcp(&tp);
|
||||||
|
else
|
||||||
|
bootp(&tp);
|
||||||
|
|
||||||
|
/* Free the data associated with the options. */
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
if (tp.options[i].len && tp.options[i].data)
|
||||||
|
free(tp.options[i].data);
|
||||||
|
}
|
253
sbin/dhclient/packet.c
Normal file
253
sbin/dhclient/packet.c
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
/* $OpenBSD: packet.c,v 1.9 2004/05/04 18:58:50 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Packet assembly code, originally contributed by Archie Cobbs. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1999 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
#include <netinet/in_systm.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <netinet/udp.h>
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
|
||||||
|
#define ETHER_HEADER_SIZE (ETHER_ADDR_LEN * 2 + sizeof(u_int16_t))
|
||||||
|
|
||||||
|
u_int32_t checksum(unsigned char *, unsigned, u_int32_t);
|
||||||
|
u_int32_t wrapsum(u_int32_t);
|
||||||
|
|
||||||
|
void assemble_ethernet_header(struct interface_info *, unsigned char *,
|
||||||
|
int *, struct hardware *);
|
||||||
|
ssize_t decode_ethernet_header(struct interface_info *, unsigned char *,
|
||||||
|
int bufix, struct hardware *);
|
||||||
|
|
||||||
|
u_int32_t
|
||||||
|
checksum(unsigned char *buf, unsigned nbytes, u_int32_t sum)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Checksum all the pairs of bytes first... */
|
||||||
|
for (i = 0; i < (nbytes & ~1U); i += 2) {
|
||||||
|
sum += (u_int16_t)ntohs(*((u_int16_t *)(buf + i)));
|
||||||
|
if (sum > 0xFFFF)
|
||||||
|
sum -= 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there's a single byte left over, checksum it, too.
|
||||||
|
* Network byte order is big-endian, so the remaining byte is
|
||||||
|
* the high byte.
|
||||||
|
*/
|
||||||
|
if (i < nbytes) {
|
||||||
|
sum += buf[i] << 8;
|
||||||
|
if (sum > 0xFFFF)
|
||||||
|
sum -= 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int32_t
|
||||||
|
wrapsum(u_int32_t sum)
|
||||||
|
{
|
||||||
|
sum = ~sum & 0xFFFF;
|
||||||
|
return (htons(sum));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
assemble_hw_header(struct interface_info *interface, unsigned char *buf,
|
||||||
|
int *bufix, struct hardware *to)
|
||||||
|
{
|
||||||
|
struct ether_header eh;
|
||||||
|
|
||||||
|
if (to != NULL && to->hlen == 6) /* XXX */
|
||||||
|
memcpy(eh.ether_dhost, to->haddr, sizeof(eh.ether_dhost));
|
||||||
|
else
|
||||||
|
memset(eh.ether_dhost, 0xff, sizeof(eh.ether_dhost));
|
||||||
|
if (interface->hw_address.hlen == sizeof(eh.ether_shost))
|
||||||
|
memcpy(eh.ether_shost, interface->hw_address.haddr,
|
||||||
|
sizeof(eh.ether_shost));
|
||||||
|
else
|
||||||
|
memset(eh.ether_shost, 0x00, sizeof(eh.ether_shost));
|
||||||
|
|
||||||
|
eh.ether_type = htons(ETHERTYPE_IP);
|
||||||
|
|
||||||
|
memcpy(&buf[*bufix], &eh, ETHER_HEADER_SIZE);
|
||||||
|
*bufix += ETHER_HEADER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
assemble_udp_ip_header(unsigned char *buf, int *bufix, u_int32_t from,
|
||||||
|
u_int32_t to, unsigned int port, unsigned char *data, int len)
|
||||||
|
{
|
||||||
|
struct ip ip;
|
||||||
|
struct udphdr udp;
|
||||||
|
|
||||||
|
ip.ip_v = 4;
|
||||||
|
ip.ip_hl = 5;
|
||||||
|
ip.ip_tos = IPTOS_LOWDELAY;
|
||||||
|
ip.ip_len = htons(sizeof(ip) + sizeof(udp) + len);
|
||||||
|
ip.ip_id = 0;
|
||||||
|
ip.ip_off = 0;
|
||||||
|
ip.ip_ttl = 16;
|
||||||
|
ip.ip_p = IPPROTO_UDP;
|
||||||
|
ip.ip_sum = 0;
|
||||||
|
ip.ip_src.s_addr = from;
|
||||||
|
ip.ip_dst.s_addr = to;
|
||||||
|
|
||||||
|
ip.ip_sum = wrapsum(checksum((unsigned char *)&ip, sizeof(ip), 0));
|
||||||
|
memcpy(&buf[*bufix], &ip, sizeof(ip));
|
||||||
|
*bufix += sizeof(ip);
|
||||||
|
|
||||||
|
udp.uh_sport = htons(LOCAL_PORT); /* XXX */
|
||||||
|
udp.uh_dport = port; /* XXX */
|
||||||
|
udp.uh_ulen = htons(sizeof(udp) + len);
|
||||||
|
memset(&udp.uh_sum, 0, sizeof(udp.uh_sum));
|
||||||
|
|
||||||
|
udp.uh_sum = wrapsum(checksum((unsigned char *)&udp, sizeof(udp),
|
||||||
|
checksum(data, len, checksum((unsigned char *)&ip.ip_src,
|
||||||
|
2 * sizeof(ip.ip_src),
|
||||||
|
IPPROTO_UDP + (u_int32_t)ntohs(udp.uh_ulen)))));
|
||||||
|
|
||||||
|
memcpy(&buf[*bufix], &udp, sizeof(udp));
|
||||||
|
*bufix += sizeof(udp);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
decode_hw_header(unsigned char *buf, int bufix, struct hardware *from)
|
||||||
|
{
|
||||||
|
struct ether_header eh;
|
||||||
|
|
||||||
|
memcpy(&eh, buf + bufix, ETHER_HEADER_SIZE);
|
||||||
|
|
||||||
|
memcpy(from->haddr, eh.ether_shost, sizeof(eh.ether_shost));
|
||||||
|
from->htype = ARPHRD_ETHER;
|
||||||
|
from->hlen = sizeof(eh.ether_shost);
|
||||||
|
|
||||||
|
return (sizeof(eh));
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
decode_udp_ip_header(unsigned char *buf, int bufix, struct sockaddr_in *from,
|
||||||
|
unsigned char *data, int buflen)
|
||||||
|
{
|
||||||
|
struct ip *ip;
|
||||||
|
struct udphdr *udp;
|
||||||
|
u_int32_t ip_len = (buf[bufix] & 0xf) << 2;
|
||||||
|
u_int32_t sum, usum;
|
||||||
|
static int ip_packets_seen;
|
||||||
|
static int ip_packets_bad_checksum;
|
||||||
|
static int udp_packets_seen;
|
||||||
|
static int udp_packets_bad_checksum;
|
||||||
|
static int udp_packets_length_checked;
|
||||||
|
static int udp_packets_length_overflow;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
ip = (struct ip *)(buf + bufix);
|
||||||
|
udp = (struct udphdr *)(buf + bufix + ip_len);
|
||||||
|
|
||||||
|
/* Check the IP header checksum - it should be zero. */
|
||||||
|
ip_packets_seen++;
|
||||||
|
if (wrapsum(checksum(buf + bufix, ip_len, 0)) != 0) {
|
||||||
|
ip_packets_bad_checksum++;
|
||||||
|
if (ip_packets_seen > 4 &&
|
||||||
|
(ip_packets_seen / ip_packets_bad_checksum) < 2) {
|
||||||
|
note("%d bad IP checksums seen in %d packets",
|
||||||
|
ip_packets_bad_checksum, ip_packets_seen);
|
||||||
|
ip_packets_seen = ip_packets_bad_checksum = 0;
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ntohs(ip->ip_len) != buflen)
|
||||||
|
debug("ip length %d disagrees with bytes received %d.",
|
||||||
|
ntohs(ip->ip_len), buflen);
|
||||||
|
|
||||||
|
memcpy(&from->sin_addr, &ip->ip_src, 4);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute UDP checksums, including the ``pseudo-header'', the
|
||||||
|
* UDP header and the data. If the UDP checksum field is zero,
|
||||||
|
* we're not supposed to do a checksum.
|
||||||
|
*/
|
||||||
|
if (!data) {
|
||||||
|
data = buf + bufix + ip_len + sizeof(*udp);
|
||||||
|
len = ntohs(udp->uh_ulen) - sizeof(*udp);
|
||||||
|
udp_packets_length_checked++;
|
||||||
|
if (len + data > buf + bufix + buflen) {
|
||||||
|
udp_packets_length_overflow++;
|
||||||
|
if (udp_packets_length_checked > 4 &&
|
||||||
|
(udp_packets_length_checked /
|
||||||
|
udp_packets_length_overflow) < 2) {
|
||||||
|
note("%d udp packets in %d too long - dropped",
|
||||||
|
udp_packets_length_overflow,
|
||||||
|
udp_packets_length_checked);
|
||||||
|
udp_packets_length_overflow =
|
||||||
|
udp_packets_length_checked = 0;
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (len + data != buf + bufix + buflen)
|
||||||
|
debug("accepting packet with data after udp payload.");
|
||||||
|
}
|
||||||
|
|
||||||
|
usum = udp->uh_sum;
|
||||||
|
udp->uh_sum = 0;
|
||||||
|
|
||||||
|
sum = wrapsum(checksum((unsigned char *)udp, sizeof(*udp),
|
||||||
|
checksum(data, len, checksum((unsigned char *)&ip->ip_src,
|
||||||
|
2 * sizeof(ip->ip_src),
|
||||||
|
IPPROTO_UDP + (u_int32_t)ntohs(udp->uh_ulen)))));
|
||||||
|
|
||||||
|
udp_packets_seen++;
|
||||||
|
if (usum && usum != sum) {
|
||||||
|
udp_packets_bad_checksum++;
|
||||||
|
if (udp_packets_seen > 4 &&
|
||||||
|
(udp_packets_seen / udp_packets_bad_checksum) < 2) {
|
||||||
|
note("%d bad udp checksums in %d packets",
|
||||||
|
udp_packets_bad_checksum, udp_packets_seen);
|
||||||
|
udp_packets_seen = udp_packets_bad_checksum = 0;
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&from->sin_port, &udp->uh_sport, sizeof(udp->uh_sport));
|
||||||
|
|
||||||
|
return (ip_len + sizeof(*udp));
|
||||||
|
}
|
577
sbin/dhclient/parse.c
Normal file
577
sbin/dhclient/parse.c
Normal file
@ -0,0 +1,577 @@
|
|||||||
|
/* $OpenBSD: parse.c,v 1.11 2004/05/05 23:07:47 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Common parser code for dhcpd and dhclient. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
#include "dhctoken.h"
|
||||||
|
|
||||||
|
/* Skip to the semicolon ending the current statement. If we encounter
|
||||||
|
* braces, the matching closing brace terminates the statement. If we
|
||||||
|
* encounter a right brace but haven't encountered a left brace, return
|
||||||
|
* leaving the brace in the token buffer for the caller. If we see a
|
||||||
|
* semicolon and haven't seen a left brace, return. This lets us skip
|
||||||
|
* over:
|
||||||
|
*
|
||||||
|
* statement;
|
||||||
|
* statement foo bar { }
|
||||||
|
* statement foo bar { statement { } }
|
||||||
|
* statement}
|
||||||
|
*
|
||||||
|
* ...et cetera.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
skip_to_semi(FILE *cfile)
|
||||||
|
{
|
||||||
|
int brace_count = 0, token;
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = peek_token(&val, cfile);
|
||||||
|
if (token == RBRACE) {
|
||||||
|
if (brace_count) {
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (!--brace_count)
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
} else if (token == LBRACE) {
|
||||||
|
brace_count++;
|
||||||
|
} else if (token == SEMI && !brace_count) {
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
return;
|
||||||
|
} else if (token == '\n') {
|
||||||
|
/*
|
||||||
|
* EOL only happens when parsing
|
||||||
|
* /etc/resolv.conf, and we treat it like a
|
||||||
|
* semicolon because the resolv.conf file is
|
||||||
|
* line-oriented.
|
||||||
|
*/
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
} while (token != EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parse_semi(FILE *cfile)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("semicolon expected.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* string-parameter :== STRING SEMI
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
parse_string(FILE *cfile)
|
||||||
|
{
|
||||||
|
char *val, *s;
|
||||||
|
int token;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != STRING) {
|
||||||
|
parse_warn("filename must be a string");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
s = malloc(strlen(val) + 1);
|
||||||
|
if (!s)
|
||||||
|
error("no memory for string %s.", val);
|
||||||
|
strlcpy(s, val, strlen(val) + 1);
|
||||||
|
|
||||||
|
if (!parse_semi(cfile))
|
||||||
|
return (NULL);
|
||||||
|
return (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parse_ip_addr(FILE *cfile, struct iaddr *addr)
|
||||||
|
{
|
||||||
|
addr->len = 4;
|
||||||
|
if (parse_numeric_aggregate(cfile, addr->iabuf,
|
||||||
|
&addr->len, DOT, 10, 8))
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hardware-parameter :== HARDWARE ETHERNET csns SEMI
|
||||||
|
* csns :== NUMBER | csns COLON NUMBER
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse_hardware_param(FILE *cfile, struct hardware *hardware)
|
||||||
|
{
|
||||||
|
unsigned char *t;
|
||||||
|
int token, hlen;
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
switch (token) {
|
||||||
|
case ETHERNET:
|
||||||
|
hardware->htype = HTYPE_ETHER;
|
||||||
|
break;
|
||||||
|
case TOKEN_RING:
|
||||||
|
hardware->htype = HTYPE_IEEE802;
|
||||||
|
break;
|
||||||
|
case FDDI:
|
||||||
|
hardware->htype = HTYPE_FDDI;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
parse_warn("expecting a network hardware type");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the hardware address information. Technically, it
|
||||||
|
* would make a lot of sense to restrict the length of the data
|
||||||
|
* we'll accept here to the length of a particular hardware
|
||||||
|
* address type. Unfortunately, there are some broken clients
|
||||||
|
* out there that put bogus data in the chaddr buffer, and we
|
||||||
|
* accept that data in the lease file rather than simply failing
|
||||||
|
* on such clients. Yuck.
|
||||||
|
*/
|
||||||
|
hlen = 0;
|
||||||
|
t = parse_numeric_aggregate(cfile, NULL, &hlen, COLON, 16, 8);
|
||||||
|
if (!t)
|
||||||
|
return;
|
||||||
|
if (hlen > sizeof(hardware->haddr)) {
|
||||||
|
free(t);
|
||||||
|
parse_warn("hardware address too long");
|
||||||
|
} else {
|
||||||
|
hardware->hlen = hlen;
|
||||||
|
memcpy((unsigned char *)&hardware->haddr[0], t,
|
||||||
|
hardware->hlen);
|
||||||
|
if (hlen < sizeof(hardware->haddr))
|
||||||
|
memset(&hardware->haddr[hlen], 0,
|
||||||
|
sizeof(hardware->haddr) - hlen);
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("expecting semicolon.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lease-time :== NUMBER SEMI
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
parse_lease_time(FILE *cfile, time_t *timep)
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int token;
|
||||||
|
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn("Expecting numeric lease time");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
convert_num((unsigned char *)timep, val, 10, 32);
|
||||||
|
/* Unswap the number - convert_num returns stuff in NBO. */
|
||||||
|
*timep = ntohl(*timep); /* XXX */
|
||||||
|
|
||||||
|
parse_semi(cfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No BNF for numeric aggregates - that's defined by the caller. What
|
||||||
|
* this function does is to parse a sequence of numbers separated by the
|
||||||
|
* token specified in separator. If max is zero, any number of numbers
|
||||||
|
* will be parsed; otherwise, exactly max numbers are expected. Base
|
||||||
|
* and size tell us how to internalize the numbers once they've been
|
||||||
|
* tokenized.
|
||||||
|
*/
|
||||||
|
unsigned char *
|
||||||
|
parse_numeric_aggregate(FILE *cfile, unsigned char *buf, int *max,
|
||||||
|
int separator, int base, int size)
|
||||||
|
{
|
||||||
|
unsigned char *bufp = buf, *s = NULL;
|
||||||
|
int token, count = 0;
|
||||||
|
char *val, *t;
|
||||||
|
pair c = NULL;
|
||||||
|
|
||||||
|
if (!bufp && *max) {
|
||||||
|
bufp = malloc(*max * size / 8);
|
||||||
|
if (!bufp)
|
||||||
|
error("can't allocate space for numeric aggregate");
|
||||||
|
} else
|
||||||
|
s = bufp;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (count) {
|
||||||
|
token = peek_token(&val, cfile);
|
||||||
|
if (token != separator) {
|
||||||
|
if (!*max)
|
||||||
|
break;
|
||||||
|
if (token != RBRACE && token != LBRACE)
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
parse_warn("too few numbers.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
}
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
|
||||||
|
if (token == EOF) {
|
||||||
|
parse_warn("unexpected end of file");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow NUMBER_OR_NAME if base is 16. */
|
||||||
|
if (token != NUMBER &&
|
||||||
|
(base != 16 || token != NUMBER_OR_NAME)) {
|
||||||
|
parse_warn("expecting numeric value.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If we can, convert the number now; otherwise, build a
|
||||||
|
* linked list of all the numbers.
|
||||||
|
*/
|
||||||
|
if (s) {
|
||||||
|
convert_num(s, val, base, size);
|
||||||
|
s += size / 8;
|
||||||
|
} else {
|
||||||
|
t = malloc(strlen(val) + 1);
|
||||||
|
if (!t)
|
||||||
|
error("no temp space for number.");
|
||||||
|
strlcpy(t, val, strlen(val) + 1);
|
||||||
|
c = cons(t, c);
|
||||||
|
}
|
||||||
|
} while (++count != *max);
|
||||||
|
|
||||||
|
/* If we had to cons up a list, convert it now. */
|
||||||
|
if (c) {
|
||||||
|
bufp = malloc(count * size / 8);
|
||||||
|
if (!bufp)
|
||||||
|
error("can't allocate space for numeric aggregate.");
|
||||||
|
s = bufp + count - size / 8;
|
||||||
|
*max = count;
|
||||||
|
}
|
||||||
|
while (c) {
|
||||||
|
pair cdr = c->cdr;
|
||||||
|
convert_num(s, (char *)c->car, base, size);
|
||||||
|
s -= size / 8;
|
||||||
|
/* Free up temp space. */
|
||||||
|
free(c->car);
|
||||||
|
free(c);
|
||||||
|
c = cdr;
|
||||||
|
}
|
||||||
|
return (bufp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
convert_num(unsigned char *buf, char *str, int base, int size)
|
||||||
|
{
|
||||||
|
int negative = 0, tval, max;
|
||||||
|
u_int32_t val = 0;
|
||||||
|
char *ptr = str;
|
||||||
|
|
||||||
|
if (*ptr == '-') {
|
||||||
|
negative = 1;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If base wasn't specified, figure it out from the data. */
|
||||||
|
if (!base) {
|
||||||
|
if (ptr[0] == '0') {
|
||||||
|
if (ptr[1] == 'x') {
|
||||||
|
base = 16;
|
||||||
|
ptr += 2;
|
||||||
|
} else if (isascii(ptr[1]) && isdigit(ptr[1])) {
|
||||||
|
base = 8;
|
||||||
|
ptr += 1;
|
||||||
|
} else
|
||||||
|
base = 10;
|
||||||
|
} else
|
||||||
|
base = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
tval = *ptr++;
|
||||||
|
/* XXX assumes ASCII... */
|
||||||
|
if (tval >= 'a')
|
||||||
|
tval = tval - 'a' + 10;
|
||||||
|
else if (tval >= 'A')
|
||||||
|
tval = tval - 'A' + 10;
|
||||||
|
else if (tval >= '0')
|
||||||
|
tval -= '0';
|
||||||
|
else {
|
||||||
|
warning("Bogus number: %s.", str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tval >= base) {
|
||||||
|
warning("Bogus number: %s: digit %d not in base %d",
|
||||||
|
str, tval, base);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
val = val * base + tval;
|
||||||
|
} while (*ptr);
|
||||||
|
|
||||||
|
if (negative)
|
||||||
|
max = (1 << (size - 1));
|
||||||
|
else
|
||||||
|
max = (1 << (size - 1)) + ((1 << (size - 1)) - 1);
|
||||||
|
if (val > max) {
|
||||||
|
switch (base) {
|
||||||
|
case 8:
|
||||||
|
warning("value %s%o exceeds max (%d) for precision.",
|
||||||
|
negative ? "-" : "", val, max);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
warning("value %s%x exceeds max (%d) for precision.",
|
||||||
|
negative ? "-" : "", val, max);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warning("value %s%u exceeds max (%d) for precision.",
|
||||||
|
negative ? "-" : "", val, max);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negative)
|
||||||
|
switch (size) {
|
||||||
|
case 8:
|
||||||
|
*buf = -(unsigned long)val;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
putShort(buf, -(unsigned long)val);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
putLong(buf, -(unsigned long)val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warning("Unexpected integer size: %d", size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch (size) {
|
||||||
|
case 8:
|
||||||
|
*buf = (u_int8_t)val;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
putUShort(buf, (u_int16_t)val);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
putULong(buf, val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warning("Unexpected integer size: %d", size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
|
||||||
|
* NUMBER COLON NUMBER COLON NUMBER SEMI
|
||||||
|
*
|
||||||
|
* Dates are always in GMT; first number is day of week; next is
|
||||||
|
* year/month/day; next is hours:minutes:seconds on a 24-hour
|
||||||
|
* clock.
|
||||||
|
*/
|
||||||
|
time_t
|
||||||
|
parse_date(FILE *cfile)
|
||||||
|
{
|
||||||
|
static int months[11] = { 31, 59, 90, 120, 151, 181,
|
||||||
|
212, 243, 273, 304, 334 };
|
||||||
|
int guess, token;
|
||||||
|
struct tm tm;
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
/* Day of week... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn("numeric day of week expected.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
tm.tm_wday = atoi(val);
|
||||||
|
|
||||||
|
/* Year... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn("numeric year expected.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
tm.tm_year = atoi(val);
|
||||||
|
if (tm.tm_year > 1900)
|
||||||
|
tm.tm_year -= 1900;
|
||||||
|
|
||||||
|
/* Slash separating year from month... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != SLASH) {
|
||||||
|
parse_warn("expected slash separating year from month.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Month... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn("numeric month expected.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
tm.tm_mon = atoi(val) - 1;
|
||||||
|
|
||||||
|
/* Slash separating month from day... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != SLASH) {
|
||||||
|
parse_warn("expected slash separating month from day.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Month... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn("numeric day of month expected.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
tm.tm_mday = atoi(val);
|
||||||
|
|
||||||
|
/* Hour... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn("numeric hour expected.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
tm.tm_hour = atoi(val);
|
||||||
|
|
||||||
|
/* Colon separating hour from minute... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != COLON) {
|
||||||
|
parse_warn("expected colon separating hour from minute.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Minute... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn("numeric minute expected.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
tm.tm_min = atoi(val);
|
||||||
|
|
||||||
|
/* Colon separating minute from second... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != COLON) {
|
||||||
|
parse_warn("expected colon separating hour from minute.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Minute... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != NUMBER) {
|
||||||
|
parse_warn("numeric minute expected.");
|
||||||
|
if (token != SEMI)
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
tm.tm_sec = atoi(val);
|
||||||
|
tm.tm_isdst = 0;
|
||||||
|
|
||||||
|
/* XXX: We assume that mktime does not use tm_yday. */
|
||||||
|
tm.tm_yday = 0;
|
||||||
|
|
||||||
|
/* Make sure the date ends in a semicolon... */
|
||||||
|
token = next_token(&val, cfile);
|
||||||
|
if (token != SEMI) {
|
||||||
|
parse_warn("semicolon expected.");
|
||||||
|
skip_to_semi(cfile);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Guess the time value... */
|
||||||
|
guess = ((((((365 * (tm.tm_year - 70) + /* Days in years since '70 */
|
||||||
|
(tm.tm_year - 69) / 4 + /* Leap days since '70 */
|
||||||
|
(tm.tm_mon /* Days in months this year */
|
||||||
|
? months[tm.tm_mon - 1]
|
||||||
|
: 0) +
|
||||||
|
(tm.tm_mon > 1 && /* Leap day this year */
|
||||||
|
!((tm.tm_year - 72) & 3)) +
|
||||||
|
tm.tm_mday - 1) * 24) + /* Day of month */
|
||||||
|
tm.tm_hour) * 60) +
|
||||||
|
tm.tm_min) * 60) + tm.tm_sec;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This guess could be wrong because of leap seconds or other
|
||||||
|
* weirdness we don't know about that the system does. For
|
||||||
|
* now, we're just going to accept the guess, but at some point
|
||||||
|
* it might be nice to do a successive approximation here to get
|
||||||
|
* an exact value. Even if the error is small, if the server
|
||||||
|
* is restarted frequently (and thus the lease database is
|
||||||
|
* reread), the error could accumulate into something
|
||||||
|
* significant.
|
||||||
|
*/
|
||||||
|
return (guess);
|
||||||
|
}
|
235
sbin/dhclient/privsep.c
Normal file
235
sbin/dhclient/privsep.c
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/* $OpenBSD: privsep.c,v 1.7 2004/05/10 18:34:42 deraadt Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||||
|
* OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
#include "privsep.h"
|
||||||
|
|
||||||
|
struct buf *
|
||||||
|
buf_open(size_t len)
|
||||||
|
{
|
||||||
|
struct buf *buf;
|
||||||
|
|
||||||
|
if ((buf = calloc(1, sizeof(struct buf))) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
if ((buf->buf = malloc(len)) == NULL) {
|
||||||
|
free(buf);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
buf->size = len;
|
||||||
|
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
buf_add(struct buf *buf, void *data, size_t len)
|
||||||
|
{
|
||||||
|
if (buf->wpos + len > buf->size)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
memcpy(buf->buf + buf->wpos, data, len);
|
||||||
|
buf->wpos += len;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
buf_close(int sock, struct buf *buf)
|
||||||
|
{
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
do {
|
||||||
|
n = write(sock, buf->buf + buf->rpos, buf->size - buf->rpos);
|
||||||
|
if (n != -1)
|
||||||
|
buf->rpos += n;
|
||||||
|
if (n == 0) { /* connection closed */
|
||||||
|
errno = 0;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
} while (n == -1 && (errno == EAGAIN || errno == EINTR));
|
||||||
|
|
||||||
|
if (buf->rpos < buf->size)
|
||||||
|
error("short write: wanted %lu got %ld bytes",
|
||||||
|
(unsigned long)buf->size, (long)buf->rpos);
|
||||||
|
|
||||||
|
free(buf->buf);
|
||||||
|
free(buf);
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
buf_read(int sock, void *buf, size_t nbytes)
|
||||||
|
{
|
||||||
|
ssize_t n, r = 0;
|
||||||
|
char *p = buf;
|
||||||
|
|
||||||
|
do {
|
||||||
|
n = read(sock, p, nbytes);
|
||||||
|
if (n == 0)
|
||||||
|
error("connection closed");
|
||||||
|
if (n != -1) {
|
||||||
|
r += n;
|
||||||
|
p += n;
|
||||||
|
nbytes -= n;
|
||||||
|
}
|
||||||
|
} while (n == -1 && (errno == EINTR || errno == EAGAIN));
|
||||||
|
|
||||||
|
if (n == -1)
|
||||||
|
error("buf_read: %m");
|
||||||
|
|
||||||
|
if (r < nbytes)
|
||||||
|
error("short read: wanted %lu got %ld bytes",
|
||||||
|
(unsigned long)nbytes, (long)r);
|
||||||
|
|
||||||
|
return (r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dispatch_imsg(int fd)
|
||||||
|
{
|
||||||
|
struct imsg_hdr hdr;
|
||||||
|
char *medium, *reason, *filename,
|
||||||
|
*servername, *prefix;
|
||||||
|
size_t medium_len, reason_len, filename_len,
|
||||||
|
servername_len, prefix_len, totlen;
|
||||||
|
struct client_lease lease;
|
||||||
|
int ret, i, optlen;
|
||||||
|
struct buf *buf;
|
||||||
|
|
||||||
|
buf_read(fd, &hdr, sizeof(hdr));
|
||||||
|
|
||||||
|
switch (hdr.code) {
|
||||||
|
case IMSG_SCRIPT_INIT:
|
||||||
|
if (hdr.len < sizeof(hdr) + sizeof(size_t))
|
||||||
|
error("corrupted message received");
|
||||||
|
buf_read(fd, &medium_len, sizeof(medium_len));
|
||||||
|
if (hdr.len < medium_len + sizeof(size_t) + sizeof(hdr)
|
||||||
|
+ sizeof(size_t) || medium_len == SIZE_T_MAX)
|
||||||
|
error("corrupted message received");
|
||||||
|
if (medium_len > 0) {
|
||||||
|
if ((medium = calloc(1, medium_len + 1)) == NULL)
|
||||||
|
error("%m");
|
||||||
|
buf_read(fd, medium, medium_len);
|
||||||
|
} else
|
||||||
|
medium = NULL;
|
||||||
|
|
||||||
|
buf_read(fd, &reason_len, sizeof(reason_len));
|
||||||
|
if (hdr.len < medium_len + reason_len + sizeof(hdr) ||
|
||||||
|
reason_len == SIZE_T_MAX)
|
||||||
|
error("corrupted message received");
|
||||||
|
if (reason_len > 0) {
|
||||||
|
if ((reason = calloc(1, reason_len + 1)) == NULL)
|
||||||
|
error("%m");
|
||||||
|
buf_read(fd, reason, reason_len);
|
||||||
|
} else
|
||||||
|
reason = NULL;
|
||||||
|
|
||||||
|
priv_script_init(reason, medium);
|
||||||
|
free(reason);
|
||||||
|
free(medium);
|
||||||
|
break;
|
||||||
|
case IMSG_SCRIPT_WRITE_PARAMS:
|
||||||
|
bzero(&lease, sizeof lease);
|
||||||
|
totlen = sizeof(hdr) + sizeof(lease) + sizeof(size_t);
|
||||||
|
if (hdr.len < totlen)
|
||||||
|
error("corrupted message received");
|
||||||
|
buf_read(fd, &lease, sizeof(lease));
|
||||||
|
|
||||||
|
buf_read(fd, &filename_len, sizeof(filename_len));
|
||||||
|
totlen += filename_len + sizeof(size_t);
|
||||||
|
if (hdr.len < totlen || filename_len == SIZE_T_MAX)
|
||||||
|
error("corrupted message received");
|
||||||
|
if (filename_len > 0) {
|
||||||
|
if ((filename = calloc(1, filename_len + 1)) == NULL)
|
||||||
|
error("%m");
|
||||||
|
buf_read(fd, filename, filename_len);
|
||||||
|
} else
|
||||||
|
filename = NULL;
|
||||||
|
|
||||||
|
buf_read(fd, &servername_len, sizeof(servername_len));
|
||||||
|
totlen += servername_len + sizeof(size_t);
|
||||||
|
if (hdr.len < totlen || servername_len == SIZE_T_MAX)
|
||||||
|
error("corrupted message received");
|
||||||
|
if (servername_len > 0) {
|
||||||
|
if ((servername =
|
||||||
|
calloc(1, servername_len + 1)) == NULL)
|
||||||
|
error("%m");
|
||||||
|
buf_read(fd, servername, servername_len);
|
||||||
|
} else
|
||||||
|
servername = NULL;
|
||||||
|
|
||||||
|
buf_read(fd, &prefix_len, sizeof(prefix_len));
|
||||||
|
totlen += prefix_len;
|
||||||
|
if (hdr.len < totlen || prefix_len == SIZE_T_MAX)
|
||||||
|
error("corrupted message received");
|
||||||
|
if (prefix_len > 0) {
|
||||||
|
if ((prefix = calloc(1, prefix_len + 1)) == NULL)
|
||||||
|
error("%m");
|
||||||
|
buf_read(fd, prefix, prefix_len);
|
||||||
|
} else
|
||||||
|
prefix = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
totlen += sizeof(optlen);
|
||||||
|
if (hdr.len < totlen)
|
||||||
|
error("corrupted message received");
|
||||||
|
buf_read(fd, &optlen, sizeof(optlen));
|
||||||
|
lease.options[i].data = NULL;
|
||||||
|
lease.options[i].len = optlen;
|
||||||
|
if (optlen > 0) {
|
||||||
|
totlen += optlen;
|
||||||
|
if (hdr.len < totlen || optlen == SIZE_T_MAX)
|
||||||
|
error("corrupted message received");
|
||||||
|
lease.options[i].data =
|
||||||
|
calloc(1, optlen + 1);
|
||||||
|
if (lease.options[i].data == NULL)
|
||||||
|
error("%m");
|
||||||
|
buf_read(fd, lease.options[i].data, optlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lease.server_name = servername;
|
||||||
|
lease.filename = filename;
|
||||||
|
|
||||||
|
priv_script_write_params(prefix, &lease);
|
||||||
|
|
||||||
|
free(servername);
|
||||||
|
free(filename);
|
||||||
|
free(prefix);
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
if (lease.options[i].len > 0)
|
||||||
|
free(lease.options[i].data);
|
||||||
|
break;
|
||||||
|
case IMSG_SCRIPT_GO:
|
||||||
|
if (hdr.len != sizeof(hdr))
|
||||||
|
error("corrupted message received");
|
||||||
|
|
||||||
|
ret = priv_script_go();
|
||||||
|
|
||||||
|
hdr.code = IMSG_SCRIPT_GO_RET;
|
||||||
|
hdr.len = sizeof(struct imsg_hdr) + sizeof(int);
|
||||||
|
if ((buf = buf_open(hdr.len)) == NULL)
|
||||||
|
error("buf_open: %m");
|
||||||
|
if (buf_add(buf, &hdr, sizeof(hdr)))
|
||||||
|
error("buf_add: %m");
|
||||||
|
if (buf_add(buf, &ret, sizeof(ret)))
|
||||||
|
error("buf_add: %m");
|
||||||
|
if (buf_close(fd, buf) == -1)
|
||||||
|
error("buf_close: %m");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("received unknown message, code %d", hdr.code);
|
||||||
|
}
|
||||||
|
}
|
47
sbin/dhclient/privsep.h
Normal file
47
sbin/dhclient/privsep.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* $OpenBSD: privsep.h,v 1.2 2004/05/04 18:51:18 henning Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||||
|
* OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
struct buf {
|
||||||
|
u_char *buf;
|
||||||
|
size_t size;
|
||||||
|
size_t wpos;
|
||||||
|
size_t rpos;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum imsg_code {
|
||||||
|
IMSG_NONE,
|
||||||
|
IMSG_SCRIPT_INIT,
|
||||||
|
IMSG_SCRIPT_WRITE_PARAMS,
|
||||||
|
IMSG_SCRIPT_GO,
|
||||||
|
IMSG_SCRIPT_GO_RET
|
||||||
|
};
|
||||||
|
|
||||||
|
struct imsg_hdr {
|
||||||
|
enum imsg_code code;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct buf *buf_open(size_t);
|
||||||
|
int buf_add(struct buf *, void *, size_t);
|
||||||
|
int buf_close(int, struct buf *);
|
||||||
|
ssize_t buf_read(int sock, void *, size_t);
|
430
sbin/dhclient/tables.c
Normal file
430
sbin/dhclient/tables.c
Normal file
@ -0,0 +1,430 @@
|
|||||||
|
/* $OpenBSD: tables.c,v 1.4 2004/05/04 20:28:40 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Tables of information... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DHCP Option names, formats and codes, from RFC1533.
|
||||||
|
*
|
||||||
|
* Format codes:
|
||||||
|
*
|
||||||
|
* e - end of data
|
||||||
|
* I - IP address
|
||||||
|
* l - 32-bit signed integer
|
||||||
|
* L - 32-bit unsigned integer
|
||||||
|
* s - 16-bit signed integer
|
||||||
|
* S - 16-bit unsigned integer
|
||||||
|
* b - 8-bit signed integer
|
||||||
|
* B - 8-bit unsigned integer
|
||||||
|
* t - ASCII text
|
||||||
|
* f - flag (true or false)
|
||||||
|
* A - array of whatever precedes (e.g., IA means array of IP addresses)
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct universe dhcp_universe;
|
||||||
|
struct option dhcp_options[256] = {
|
||||||
|
{ "pad", "", &dhcp_universe, 0 },
|
||||||
|
{ "subnet-mask", "I", &dhcp_universe, 1 },
|
||||||
|
{ "time-offset", "l", &dhcp_universe, 2 },
|
||||||
|
{ "routers", "IA", &dhcp_universe, 3 },
|
||||||
|
{ "time-servers", "IA", &dhcp_universe, 4 },
|
||||||
|
{ "ien116-name-servers", "IA", &dhcp_universe, 5 },
|
||||||
|
{ "domain-name-servers", "IA", &dhcp_universe, 6 },
|
||||||
|
{ "log-servers", "IA", &dhcp_universe, 7 },
|
||||||
|
{ "cookie-servers", "IA", &dhcp_universe, 8 },
|
||||||
|
{ "lpr-servers", "IA", &dhcp_universe, 9 },
|
||||||
|
{ "impress-servers", "IA", &dhcp_universe, 10 },
|
||||||
|
{ "resource-location-servers", "IA", &dhcp_universe, 11 },
|
||||||
|
{ "host-name", "X", &dhcp_universe, 12 },
|
||||||
|
{ "boot-size", "S", &dhcp_universe, 13 },
|
||||||
|
{ "merit-dump", "t", &dhcp_universe, 14 },
|
||||||
|
{ "domain-name", "t", &dhcp_universe, 15 },
|
||||||
|
{ "swap-server", "I", &dhcp_universe, 16 },
|
||||||
|
{ "root-path", "t", &dhcp_universe, 17 },
|
||||||
|
{ "extensions-path", "t", &dhcp_universe, 18 },
|
||||||
|
{ "ip-forwarding", "f", &dhcp_universe, 19 },
|
||||||
|
{ "non-local-source-routing", "f", &dhcp_universe, 20 },
|
||||||
|
{ "policy-filter", "IIA", &dhcp_universe, 21 },
|
||||||
|
{ "max-dgram-reassembly", "S", &dhcp_universe, 22 },
|
||||||
|
{ "default-ip-ttl", "B", &dhcp_universe, 23 },
|
||||||
|
{ "path-mtu-aging-timeout", "L", &dhcp_universe, 24 },
|
||||||
|
{ "path-mtu-plateau-table", "SA", &dhcp_universe, 25 },
|
||||||
|
{ "interface-mtu", "S", &dhcp_universe, 26 },
|
||||||
|
{ "all-subnets-local", "f", &dhcp_universe, 27 },
|
||||||
|
{ "broadcast-address", "I", &dhcp_universe, 28 },
|
||||||
|
{ "perform-mask-discovery", "f", &dhcp_universe, 29 },
|
||||||
|
{ "mask-supplier", "f", &dhcp_universe, 30 },
|
||||||
|
{ "router-discovery", "f", &dhcp_universe, 31 },
|
||||||
|
{ "router-solicitation-address", "I", &dhcp_universe, 32 },
|
||||||
|
{ "static-routes", "IIA", &dhcp_universe, 33 },
|
||||||
|
{ "trailer-encapsulation", "f", &dhcp_universe, 34 },
|
||||||
|
{ "arp-cache-timeout", "L", &dhcp_universe, 35 },
|
||||||
|
{ "ieee802-3-encapsulation", "f", &dhcp_universe, 36 },
|
||||||
|
{ "default-tcp-ttl", "B", &dhcp_universe, 37 },
|
||||||
|
{ "tcp-keepalive-interval", "L", &dhcp_universe, 38 },
|
||||||
|
{ "tcp-keepalive-garbage", "f", &dhcp_universe, 39 },
|
||||||
|
{ "nis-domain", "t", &dhcp_universe, 40 },
|
||||||
|
{ "nis-servers", "IA", &dhcp_universe, 41 },
|
||||||
|
{ "ntp-servers", "IA", &dhcp_universe, 42 },
|
||||||
|
{ "vendor-encapsulated-options", "X", &dhcp_universe, 43 },
|
||||||
|
{ "netbios-name-servers", "IA", &dhcp_universe, 44 },
|
||||||
|
{ "netbios-dd-server", "IA", &dhcp_universe, 45 },
|
||||||
|
{ "netbios-node-type", "B", &dhcp_universe, 46 },
|
||||||
|
{ "netbios-scope", "t", &dhcp_universe, 47 },
|
||||||
|
{ "font-servers", "IA", &dhcp_universe, 48 },
|
||||||
|
{ "x-display-manager", "IA", &dhcp_universe, 49 },
|
||||||
|
{ "dhcp-requested-address", "I", &dhcp_universe, 50 },
|
||||||
|
{ "dhcp-lease-time", "L", &dhcp_universe, 51 },
|
||||||
|
{ "dhcp-option-overload", "B", &dhcp_universe, 52 },
|
||||||
|
{ "dhcp-message-type", "B", &dhcp_universe, 53 },
|
||||||
|
{ "dhcp-server-identifier", "I", &dhcp_universe, 54 },
|
||||||
|
{ "dhcp-parameter-request-list", "BA", &dhcp_universe, 55 },
|
||||||
|
{ "dhcp-message", "t", &dhcp_universe, 56 },
|
||||||
|
{ "dhcp-max-message-size", "S", &dhcp_universe, 57 },
|
||||||
|
{ "dhcp-renewal-time", "L", &dhcp_universe, 58 },
|
||||||
|
{ "dhcp-rebinding-time", "L", &dhcp_universe, 59 },
|
||||||
|
{ "dhcp-class-identifier", "t", &dhcp_universe, 60 },
|
||||||
|
{ "dhcp-client-identifier", "X", &dhcp_universe, 61 },
|
||||||
|
{ "option-62", "X", &dhcp_universe, 62 },
|
||||||
|
{ "option-63", "X", &dhcp_universe, 63 },
|
||||||
|
{ "nisplus-domain", "t", &dhcp_universe, 64 },
|
||||||
|
{ "nisplus-servers", "IA", &dhcp_universe, 65 },
|
||||||
|
{ "tftp-server-name", "t", &dhcp_universe, 66 },
|
||||||
|
{ "bootfile-name", "t", &dhcp_universe, 67 },
|
||||||
|
{ "mobile-ip-home-agent", "IA", &dhcp_universe, 68 },
|
||||||
|
{ "smtp-server", "IA", &dhcp_universe, 69 },
|
||||||
|
{ "pop-server", "IA", &dhcp_universe, 70 },
|
||||||
|
{ "nntp-server", "IA", &dhcp_universe, 71 },
|
||||||
|
{ "www-server", "IA", &dhcp_universe, 72 },
|
||||||
|
{ "finger-server", "IA", &dhcp_universe, 73 },
|
||||||
|
{ "irc-server", "IA", &dhcp_universe, 74 },
|
||||||
|
{ "streettalk-server", "IA", &dhcp_universe, 75 },
|
||||||
|
{ "streettalk-directory-assistance-server", "IA", &dhcp_universe, 76 },
|
||||||
|
{ "user-class", "t", &dhcp_universe, 77 },
|
||||||
|
{ "option-78", "X", &dhcp_universe, 78 },
|
||||||
|
{ "option-79", "X", &dhcp_universe, 79 },
|
||||||
|
{ "option-80", "X", &dhcp_universe, 80 },
|
||||||
|
{ "option-81", "X", &dhcp_universe, 81 },
|
||||||
|
{ "option-82", "X", &dhcp_universe, 82 },
|
||||||
|
{ "option-83", "X", &dhcp_universe, 83 },
|
||||||
|
{ "option-84", "X", &dhcp_universe, 84 },
|
||||||
|
{ "nds-servers", "IA", &dhcp_universe, 85 },
|
||||||
|
{ "nds-tree-name", "X", &dhcp_universe, 86 },
|
||||||
|
{ "nds-context", "X", &dhcp_universe, 87 },
|
||||||
|
{ "option-88", "X", &dhcp_universe, 88 },
|
||||||
|
{ "option-89", "X", &dhcp_universe, 89 },
|
||||||
|
{ "option-90", "X", &dhcp_universe, 90 },
|
||||||
|
{ "option-91", "X", &dhcp_universe, 91 },
|
||||||
|
{ "option-92", "X", &dhcp_universe, 92 },
|
||||||
|
{ "option-93", "X", &dhcp_universe, 93 },
|
||||||
|
{ "option-94", "X", &dhcp_universe, 94 },
|
||||||
|
{ "option-95", "X", &dhcp_universe, 95 },
|
||||||
|
{ "option-96", "X", &dhcp_universe, 96 },
|
||||||
|
{ "option-97", "X", &dhcp_universe, 97 },
|
||||||
|
{ "option-98", "X", &dhcp_universe, 98 },
|
||||||
|
{ "option-99", "X", &dhcp_universe, 99 },
|
||||||
|
{ "option-100", "X", &dhcp_universe, 100 },
|
||||||
|
{ "option-101", "X", &dhcp_universe, 101 },
|
||||||
|
{ "option-102", "X", &dhcp_universe, 102 },
|
||||||
|
{ "option-103", "X", &dhcp_universe, 103 },
|
||||||
|
{ "option-104", "X", &dhcp_universe, 104 },
|
||||||
|
{ "option-105", "X", &dhcp_universe, 105 },
|
||||||
|
{ "option-106", "X", &dhcp_universe, 106 },
|
||||||
|
{ "option-107", "X", &dhcp_universe, 107 },
|
||||||
|
{ "option-108", "X", &dhcp_universe, 108 },
|
||||||
|
{ "option-109", "X", &dhcp_universe, 109 },
|
||||||
|
{ "option-110", "X", &dhcp_universe, 110 },
|
||||||
|
{ "option-111", "X", &dhcp_universe, 111 },
|
||||||
|
{ "option-112", "X", &dhcp_universe, 112 },
|
||||||
|
{ "option-113", "X", &dhcp_universe, 113 },
|
||||||
|
{ "option-114", "X", &dhcp_universe, 114 },
|
||||||
|
{ "option-115", "X", &dhcp_universe, 115 },
|
||||||
|
{ "option-116", "X", &dhcp_universe, 116 },
|
||||||
|
{ "option-117", "X", &dhcp_universe, 117 },
|
||||||
|
{ "option-118", "X", &dhcp_universe, 118 },
|
||||||
|
{ "option-119", "X", &dhcp_universe, 119 },
|
||||||
|
{ "option-120", "X", &dhcp_universe, 120 },
|
||||||
|
{ "option-121", "X", &dhcp_universe, 121 },
|
||||||
|
{ "option-122", "X", &dhcp_universe, 122 },
|
||||||
|
{ "option-123", "X", &dhcp_universe, 123 },
|
||||||
|
{ "option-124", "X", &dhcp_universe, 124 },
|
||||||
|
{ "option-125", "X", &dhcp_universe, 125 },
|
||||||
|
{ "option-126", "X", &dhcp_universe, 126 },
|
||||||
|
{ "option-127", "X", &dhcp_universe, 127 },
|
||||||
|
{ "option-128", "X", &dhcp_universe, 128 },
|
||||||
|
{ "option-129", "X", &dhcp_universe, 129 },
|
||||||
|
{ "option-130", "X", &dhcp_universe, 130 },
|
||||||
|
{ "option-131", "X", &dhcp_universe, 131 },
|
||||||
|
{ "option-132", "X", &dhcp_universe, 132 },
|
||||||
|
{ "option-133", "X", &dhcp_universe, 133 },
|
||||||
|
{ "option-134", "X", &dhcp_universe, 134 },
|
||||||
|
{ "option-135", "X", &dhcp_universe, 135 },
|
||||||
|
{ "option-136", "X", &dhcp_universe, 136 },
|
||||||
|
{ "option-137", "X", &dhcp_universe, 137 },
|
||||||
|
{ "option-138", "X", &dhcp_universe, 138 },
|
||||||
|
{ "option-139", "X", &dhcp_universe, 139 },
|
||||||
|
{ "option-140", "X", &dhcp_universe, 140 },
|
||||||
|
{ "option-141", "X", &dhcp_universe, 141 },
|
||||||
|
{ "option-142", "X", &dhcp_universe, 142 },
|
||||||
|
{ "option-143", "X", &dhcp_universe, 143 },
|
||||||
|
{ "option-144", "X", &dhcp_universe, 144 },
|
||||||
|
{ "option-145", "X", &dhcp_universe, 145 },
|
||||||
|
{ "option-146", "X", &dhcp_universe, 146 },
|
||||||
|
{ "option-147", "X", &dhcp_universe, 147 },
|
||||||
|
{ "option-148", "X", &dhcp_universe, 148 },
|
||||||
|
{ "option-149", "X", &dhcp_universe, 149 },
|
||||||
|
{ "option-150", "X", &dhcp_universe, 150 },
|
||||||
|
{ "option-151", "X", &dhcp_universe, 151 },
|
||||||
|
{ "option-152", "X", &dhcp_universe, 152 },
|
||||||
|
{ "option-153", "X", &dhcp_universe, 153 },
|
||||||
|
{ "option-154", "X", &dhcp_universe, 154 },
|
||||||
|
{ "option-155", "X", &dhcp_universe, 155 },
|
||||||
|
{ "option-156", "X", &dhcp_universe, 156 },
|
||||||
|
{ "option-157", "X", &dhcp_universe, 157 },
|
||||||
|
{ "option-158", "X", &dhcp_universe, 158 },
|
||||||
|
{ "option-159", "X", &dhcp_universe, 159 },
|
||||||
|
{ "option-160", "X", &dhcp_universe, 160 },
|
||||||
|
{ "option-161", "X", &dhcp_universe, 161 },
|
||||||
|
{ "option-162", "X", &dhcp_universe, 162 },
|
||||||
|
{ "option-163", "X", &dhcp_universe, 163 },
|
||||||
|
{ "option-164", "X", &dhcp_universe, 164 },
|
||||||
|
{ "option-165", "X", &dhcp_universe, 165 },
|
||||||
|
{ "option-166", "X", &dhcp_universe, 166 },
|
||||||
|
{ "option-167", "X", &dhcp_universe, 167 },
|
||||||
|
{ "option-168", "X", &dhcp_universe, 168 },
|
||||||
|
{ "option-169", "X", &dhcp_universe, 169 },
|
||||||
|
{ "option-170", "X", &dhcp_universe, 170 },
|
||||||
|
{ "option-171", "X", &dhcp_universe, 171 },
|
||||||
|
{ "option-172", "X", &dhcp_universe, 172 },
|
||||||
|
{ "option-173", "X", &dhcp_universe, 173 },
|
||||||
|
{ "option-174", "X", &dhcp_universe, 174 },
|
||||||
|
{ "option-175", "X", &dhcp_universe, 175 },
|
||||||
|
{ "option-176", "X", &dhcp_universe, 176 },
|
||||||
|
{ "option-177", "X", &dhcp_universe, 177 },
|
||||||
|
{ "option-178", "X", &dhcp_universe, 178 },
|
||||||
|
{ "option-179", "X", &dhcp_universe, 179 },
|
||||||
|
{ "option-180", "X", &dhcp_universe, 180 },
|
||||||
|
{ "option-181", "X", &dhcp_universe, 181 },
|
||||||
|
{ "option-182", "X", &dhcp_universe, 182 },
|
||||||
|
{ "option-183", "X", &dhcp_universe, 183 },
|
||||||
|
{ "option-184", "X", &dhcp_universe, 184 },
|
||||||
|
{ "option-185", "X", &dhcp_universe, 185 },
|
||||||
|
{ "option-186", "X", &dhcp_universe, 186 },
|
||||||
|
{ "option-187", "X", &dhcp_universe, 187 },
|
||||||
|
{ "option-188", "X", &dhcp_universe, 188 },
|
||||||
|
{ "option-189", "X", &dhcp_universe, 189 },
|
||||||
|
{ "option-190", "X", &dhcp_universe, 190 },
|
||||||
|
{ "option-191", "X", &dhcp_universe, 191 },
|
||||||
|
{ "option-192", "X", &dhcp_universe, 192 },
|
||||||
|
{ "option-193", "X", &dhcp_universe, 193 },
|
||||||
|
{ "option-194", "X", &dhcp_universe, 194 },
|
||||||
|
{ "option-195", "X", &dhcp_universe, 195 },
|
||||||
|
{ "option-196", "X", &dhcp_universe, 196 },
|
||||||
|
{ "option-197", "X", &dhcp_universe, 197 },
|
||||||
|
{ "option-198", "X", &dhcp_universe, 198 },
|
||||||
|
{ "option-199", "X", &dhcp_universe, 199 },
|
||||||
|
{ "option-200", "X", &dhcp_universe, 200 },
|
||||||
|
{ "option-201", "X", &dhcp_universe, 201 },
|
||||||
|
{ "option-202", "X", &dhcp_universe, 202 },
|
||||||
|
{ "option-203", "X", &dhcp_universe, 203 },
|
||||||
|
{ "option-204", "X", &dhcp_universe, 204 },
|
||||||
|
{ "option-205", "X", &dhcp_universe, 205 },
|
||||||
|
{ "option-206", "X", &dhcp_universe, 206 },
|
||||||
|
{ "option-207", "X", &dhcp_universe, 207 },
|
||||||
|
{ "option-208", "X", &dhcp_universe, 208 },
|
||||||
|
{ "option-209", "X", &dhcp_universe, 209 },
|
||||||
|
{ "option-210", "X", &dhcp_universe, 210 },
|
||||||
|
{ "option-211", "X", &dhcp_universe, 211 },
|
||||||
|
{ "option-212", "X", &dhcp_universe, 212 },
|
||||||
|
{ "option-213", "X", &dhcp_universe, 213 },
|
||||||
|
{ "option-214", "X", &dhcp_universe, 214 },
|
||||||
|
{ "option-215", "X", &dhcp_universe, 215 },
|
||||||
|
{ "option-216", "X", &dhcp_universe, 216 },
|
||||||
|
{ "option-217", "X", &dhcp_universe, 217 },
|
||||||
|
{ "option-218", "X", &dhcp_universe, 218 },
|
||||||
|
{ "option-219", "X", &dhcp_universe, 219 },
|
||||||
|
{ "option-220", "X", &dhcp_universe, 220 },
|
||||||
|
{ "option-221", "X", &dhcp_universe, 221 },
|
||||||
|
{ "option-222", "X", &dhcp_universe, 222 },
|
||||||
|
{ "option-223", "X", &dhcp_universe, 223 },
|
||||||
|
{ "option-224", "X", &dhcp_universe, 224 },
|
||||||
|
{ "option-225", "X", &dhcp_universe, 225 },
|
||||||
|
{ "option-226", "X", &dhcp_universe, 226 },
|
||||||
|
{ "option-227", "X", &dhcp_universe, 227 },
|
||||||
|
{ "option-228", "X", &dhcp_universe, 228 },
|
||||||
|
{ "option-229", "X", &dhcp_universe, 229 },
|
||||||
|
{ "option-230", "X", &dhcp_universe, 230 },
|
||||||
|
{ "option-231", "X", &dhcp_universe, 231 },
|
||||||
|
{ "option-232", "X", &dhcp_universe, 232 },
|
||||||
|
{ "option-233", "X", &dhcp_universe, 233 },
|
||||||
|
{ "option-234", "X", &dhcp_universe, 234 },
|
||||||
|
{ "option-235", "X", &dhcp_universe, 235 },
|
||||||
|
{ "option-236", "X", &dhcp_universe, 236 },
|
||||||
|
{ "option-237", "X", &dhcp_universe, 237 },
|
||||||
|
{ "option-238", "X", &dhcp_universe, 238 },
|
||||||
|
{ "option-239", "X", &dhcp_universe, 239 },
|
||||||
|
{ "option-240", "X", &dhcp_universe, 240 },
|
||||||
|
{ "option-241", "X", &dhcp_universe, 241 },
|
||||||
|
{ "option-242", "X", &dhcp_universe, 242 },
|
||||||
|
{ "option-243", "X", &dhcp_universe, 243 },
|
||||||
|
{ "option-244", "X", &dhcp_universe, 244 },
|
||||||
|
{ "option-245", "X", &dhcp_universe, 245 },
|
||||||
|
{ "option-246", "X", &dhcp_universe, 246 },
|
||||||
|
{ "option-247", "X", &dhcp_universe, 247 },
|
||||||
|
{ "option-248", "X", &dhcp_universe, 248 },
|
||||||
|
{ "option-249", "X", &dhcp_universe, 249 },
|
||||||
|
{ "option-250", "X", &dhcp_universe, 250 },
|
||||||
|
{ "option-251", "X", &dhcp_universe, 251 },
|
||||||
|
{ "option-252", "X", &dhcp_universe, 252 },
|
||||||
|
{ "option-253", "X", &dhcp_universe, 253 },
|
||||||
|
{ "option-254", "X", &dhcp_universe, 254 },
|
||||||
|
{ "option-end", "e", &dhcp_universe, 255 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default dhcp option priority list (this is ad hoc and should not be
|
||||||
|
* mistaken for a carefully crafted and optimized list).
|
||||||
|
*/
|
||||||
|
unsigned char dhcp_option_default_priority_list[] = {
|
||||||
|
DHO_DHCP_REQUESTED_ADDRESS,
|
||||||
|
DHO_DHCP_OPTION_OVERLOAD,
|
||||||
|
DHO_DHCP_MAX_MESSAGE_SIZE,
|
||||||
|
DHO_DHCP_RENEWAL_TIME,
|
||||||
|
DHO_DHCP_REBINDING_TIME,
|
||||||
|
DHO_DHCP_CLASS_IDENTIFIER,
|
||||||
|
DHO_DHCP_CLIENT_IDENTIFIER,
|
||||||
|
DHO_SUBNET_MASK,
|
||||||
|
DHO_TIME_OFFSET,
|
||||||
|
DHO_ROUTERS,
|
||||||
|
DHO_TIME_SERVERS,
|
||||||
|
DHO_NAME_SERVERS,
|
||||||
|
DHO_DOMAIN_NAME_SERVERS,
|
||||||
|
DHO_HOST_NAME,
|
||||||
|
DHO_LOG_SERVERS,
|
||||||
|
DHO_COOKIE_SERVERS,
|
||||||
|
DHO_LPR_SERVERS,
|
||||||
|
DHO_IMPRESS_SERVERS,
|
||||||
|
DHO_RESOURCE_LOCATION_SERVERS,
|
||||||
|
DHO_HOST_NAME,
|
||||||
|
DHO_BOOT_SIZE,
|
||||||
|
DHO_MERIT_DUMP,
|
||||||
|
DHO_DOMAIN_NAME,
|
||||||
|
DHO_SWAP_SERVER,
|
||||||
|
DHO_ROOT_PATH,
|
||||||
|
DHO_EXTENSIONS_PATH,
|
||||||
|
DHO_IP_FORWARDING,
|
||||||
|
DHO_NON_LOCAL_SOURCE_ROUTING,
|
||||||
|
DHO_POLICY_FILTER,
|
||||||
|
DHO_MAX_DGRAM_REASSEMBLY,
|
||||||
|
DHO_DEFAULT_IP_TTL,
|
||||||
|
DHO_PATH_MTU_AGING_TIMEOUT,
|
||||||
|
DHO_PATH_MTU_PLATEAU_TABLE,
|
||||||
|
DHO_INTERFACE_MTU,
|
||||||
|
DHO_ALL_SUBNETS_LOCAL,
|
||||||
|
DHO_BROADCAST_ADDRESS,
|
||||||
|
DHO_PERFORM_MASK_DISCOVERY,
|
||||||
|
DHO_MASK_SUPPLIER,
|
||||||
|
DHO_ROUTER_DISCOVERY,
|
||||||
|
DHO_ROUTER_SOLICITATION_ADDRESS,
|
||||||
|
DHO_STATIC_ROUTES,
|
||||||
|
DHO_TRAILER_ENCAPSULATION,
|
||||||
|
DHO_ARP_CACHE_TIMEOUT,
|
||||||
|
DHO_IEEE802_3_ENCAPSULATION,
|
||||||
|
DHO_DEFAULT_TCP_TTL,
|
||||||
|
DHO_TCP_KEEPALIVE_INTERVAL,
|
||||||
|
DHO_TCP_KEEPALIVE_GARBAGE,
|
||||||
|
DHO_NIS_DOMAIN,
|
||||||
|
DHO_NIS_SERVERS,
|
||||||
|
DHO_NTP_SERVERS,
|
||||||
|
DHO_VENDOR_ENCAPSULATED_OPTIONS,
|
||||||
|
DHO_NETBIOS_NAME_SERVERS,
|
||||||
|
DHO_NETBIOS_DD_SERVER,
|
||||||
|
DHO_NETBIOS_NODE_TYPE,
|
||||||
|
DHO_NETBIOS_SCOPE,
|
||||||
|
DHO_FONT_SERVERS,
|
||||||
|
DHO_X_DISPLAY_MANAGER,
|
||||||
|
DHO_DHCP_PARAMETER_REQUEST_LIST,
|
||||||
|
|
||||||
|
/* Presently-undefined options... */
|
||||||
|
62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
|
||||||
|
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
|
||||||
|
93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
|
||||||
|
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
|
||||||
|
119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
|
||||||
|
131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
|
||||||
|
143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
|
||||||
|
155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
|
||||||
|
167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
|
||||||
|
179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
|
||||||
|
191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
|
||||||
|
203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
|
||||||
|
215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
|
||||||
|
227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
|
||||||
|
239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
|
||||||
|
251, 252, 253, 254,
|
||||||
|
};
|
||||||
|
|
||||||
|
int sizeof_dhcp_option_default_priority_list =
|
||||||
|
sizeof(dhcp_option_default_priority_list);
|
||||||
|
|
||||||
|
struct hash_table universe_hash;
|
||||||
|
|
||||||
|
void
|
||||||
|
initialize_universes(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
dhcp_universe.name = "dhcp";
|
||||||
|
dhcp_universe.hash = new_hash();
|
||||||
|
if (!dhcp_universe.hash)
|
||||||
|
error("Can't allocate dhcp option hash table.");
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
dhcp_universe.options[i] = &dhcp_options[i];
|
||||||
|
add_hash(dhcp_universe.hash,
|
||||||
|
(unsigned char *)dhcp_options[i].name, 0,
|
||||||
|
(unsigned char *)&dhcp_options[i]);
|
||||||
|
}
|
||||||
|
universe_hash.hash_count = DEFAULT_HASH_SIZE;
|
||||||
|
add_hash(&universe_hash,
|
||||||
|
(unsigned char *)dhcp_universe.name, 0,
|
||||||
|
(unsigned char *)&dhcp_universe);
|
||||||
|
}
|
56
sbin/dhclient/tree.c
Normal file
56
sbin/dhclient/tree.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* $OpenBSD: tree.c,v 1.13 2004/05/06 22:29:15 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Routines for manipulating parse trees... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
extern int h_errno;
|
||||||
|
|
||||||
|
pair
|
||||||
|
cons(caddr_t car, pair cdr)
|
||||||
|
{
|
||||||
|
pair foo = calloc(1, sizeof(*foo));
|
||||||
|
if (!foo)
|
||||||
|
error("no memory for cons.");
|
||||||
|
foo->car = car;
|
||||||
|
foo->cdr = cdr;
|
||||||
|
return (foo);
|
||||||
|
}
|
66
sbin/dhclient/tree.h
Normal file
66
sbin/dhclient/tree.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* $OpenBSD: tree.h,v 1.5 2004/05/06 22:29:15 deraadt Exp $ */
|
||||||
|
|
||||||
|
/* Definitions for address trees... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM AND
|
||||||
|
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This software has been written for the Internet Software Consortium
|
||||||
|
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||||
|
* Enterprises. To learn more about the Internet Software Consortium,
|
||||||
|
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||||
|
* Enterprises, see ``http://www.vix.com''.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* A pair of pointers, suitable for making a linked list. */
|
||||||
|
typedef struct _pair {
|
||||||
|
caddr_t car;
|
||||||
|
struct _pair *cdr;
|
||||||
|
} *pair;
|
||||||
|
|
||||||
|
struct tree_cache {
|
||||||
|
unsigned char *value;
|
||||||
|
int len;
|
||||||
|
int buf_size;
|
||||||
|
time_t timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct universe {
|
||||||
|
char *name;
|
||||||
|
struct hash_table *hash;
|
||||||
|
struct option *options[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct option {
|
||||||
|
char *name;
|
||||||
|
char *format;
|
||||||
|
struct universe *universe;
|
||||||
|
unsigned char code;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user