summaryrefslogtreecommitdiff
path: root/usr.sbin/dhcp/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/dhcp/common')
-rw-r--r--usr.sbin/dhcp/common/alloc.c137
-rw-r--r--usr.sbin/dhcp/common/bpf.c131
-rw-r--r--usr.sbin/dhcp/common/conflex.c50
-rw-r--r--usr.sbin/dhcp/common/convert.c9
-rw-r--r--usr.sbin/dhcp/common/dhcp-options.5361
-rw-r--r--usr.sbin/dhcp/common/dispatch.c407
-rw-r--r--usr.sbin/dhcp/common/dns.c399
-rw-r--r--usr.sbin/dhcp/common/errwarn.c263
-rw-r--r--usr.sbin/dhcp/common/ethernet.c92
-rw-r--r--usr.sbin/dhcp/common/hash.c69
-rw-r--r--usr.sbin/dhcp/common/icmp.c27
-rw-r--r--usr.sbin/dhcp/common/inet.c28
-rw-r--r--usr.sbin/dhcp/common/inet_addr.c150
-rw-r--r--usr.sbin/dhcp/common/memory.c140
-rw-r--r--usr.sbin/dhcp/common/nit.c347
-rw-r--r--usr.sbin/dhcp/common/options.c239
-rw-r--r--usr.sbin/dhcp/common/packet.c136
-rw-r--r--usr.sbin/dhcp/common/parse.c50
-rw-r--r--usr.sbin/dhcp/common/print.c48
-rw-r--r--usr.sbin/dhcp/common/raw.c132
-rw-r--r--usr.sbin/dhcp/common/resolv.c201
-rw-r--r--usr.sbin/dhcp/common/socket.c158
-rw-r--r--usr.sbin/dhcp/common/sysconf.c134
-rw-r--r--usr.sbin/dhcp/common/tables.c43
-rw-r--r--usr.sbin/dhcp/common/tree.c12
-rw-r--r--usr.sbin/dhcp/common/upf.c299
26 files changed, 1257 insertions, 2805 deletions
diff --git a/usr.sbin/dhcp/common/alloc.c b/usr.sbin/dhcp/common/alloc.c
index 8b300ced0c1..38fe5e7536a 100644
--- a/usr.sbin/dhcp/common/alloc.c
+++ b/usr.sbin/dhcp/common/alloc.c
@@ -3,7 +3,7 @@
Memory allocation... */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,29 +40,23 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: alloc.c,v 1.1 1998/08/18 03:43:25 deraadt Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
struct dhcp_packet *dhcp_free_list;
struct packet *packet_free_list;
-VOIDPTR dmalloc (size, name)
+void * dmalloc(size, name)
int size;
char *name;
{
- VOIDPTR foo = (VOIDPTR)malloc (size);
+ void *foo = calloc(size, sizeof(char));
if (!foo)
warn ("No memory for %s.", name);
- memset (foo, 0, size);
return foo;
}
-void dfree (ptr, name)
- VOIDPTR ptr;
+void dfree(ptr, name)
+ void *ptr;
char *name;
{
if (!ptr) {
@@ -72,33 +66,45 @@ void dfree (ptr, name)
free (ptr);
}
-struct packet *new_packet (name)
+struct packet *new_packet(name)
char *name;
{
struct packet *rval;
- rval = (struct packet *)dmalloc (sizeof (struct packet), name);
+ rval = (struct packet *)dmalloc(sizeof(struct packet), name);
return rval;
}
-struct dhcp_packet *new_dhcp_packet (name)
+struct dhcp_packet *new_dhcp_packet(name)
char *name;
{
struct dhcp_packet *rval;
- rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet),
- name);
+ rval = (struct dhcp_packet *)dmalloc(sizeof(struct dhcp_packet),
+ name);
return rval;
}
-struct tree *new_tree (name)
+struct tree *new_tree(name)
char *name;
{
- struct tree *rval = dmalloc (sizeof (struct tree), name);
+ struct tree *rval = dmalloc(sizeof(struct tree), name);
+ return rval;
+}
+
+struct string_list *new_string_list(size, name)
+ size_t size;
+ char * name;
+{
+ struct string_list *rval;
+
+ rval =dmalloc(sizeof(struct string_list) + size, name);
+ if (rval != NULL)
+ rval->string = ((char *)rval) + sizeof(struct string_list);
return rval;
}
struct tree_cache *free_tree_caches;
-struct tree_cache *new_tree_cache (name)
+struct tree_cache *new_tree_cache(name)
char *name;
{
struct tree_cache *rval;
@@ -106,85 +112,83 @@ struct tree_cache *new_tree_cache (name)
if (free_tree_caches) {
rval = free_tree_caches;
free_tree_caches =
- (struct tree_cache *)(rval -> value);
+ (struct tree_cache *)(rval->value);
} else {
- rval = dmalloc (sizeof (struct tree_cache), name);
+ rval = dmalloc(sizeof(struct tree_cache), name);
if (!rval)
- error ("unable to allocate tree cache for %s.", name);
+ error("unable to allocate tree cache for %s.", name);
}
return rval;
}
-struct hash_table *new_hash_table (count, name)
+struct hash_table *new_hash_table(count, name)
int count;
char *name;
{
- struct hash_table *rval = dmalloc (sizeof (struct hash_table)
- - (DEFAULT_HASH_SIZE
- * sizeof (struct hash_bucket *))
- + (count
- * sizeof (struct hash_bucket *)),
- name);
- rval -> hash_count = count;
+ struct hash_table *rval;
+ rval = dmalloc(sizeof (struct hash_table)
+ - (DEFAULT_HASH_SIZE * sizeof(struct hash_bucket *))
+ + (count * sizeof(struct hash_bucket *)), name);
+ rval->hash_count = count;
return rval;
}
-struct hash_bucket *new_hash_bucket (name)
+struct hash_bucket *new_hash_bucket(name)
char *name;
{
- struct hash_bucket *rval = dmalloc (sizeof (struct hash_bucket), name);
+ struct hash_bucket *rval = dmalloc(sizeof(struct hash_bucket), name);
return rval;
}
-struct lease *new_leases (n, name)
+struct lease *new_leases(n, name)
int n;
char *name;
{
- struct lease *rval = dmalloc (n * sizeof (struct lease), name);
+ struct lease *rval = dmalloc(n * sizeof(struct lease), name);
return rval;
}
-struct lease *new_lease (name)
+struct lease *new_lease(name)
char *name;
{
- struct lease *rval = dmalloc (sizeof (struct lease), name);
+ struct lease *rval = dmalloc(sizeof(struct lease), name);
return rval;
}
-struct subnet *new_subnet (name)
+struct subnet *new_subnet(name)
char *name;
{
- struct subnet *rval = dmalloc (sizeof (struct subnet), name);
+ struct subnet *rval = dmalloc(sizeof(struct subnet), name);
return rval;
}
-struct class *new_class (name)
+struct class *new_class(name)
char *name;
{
- struct class *rval = dmalloc (sizeof (struct class), name);
+ struct class *rval = dmalloc(sizeof(struct class), name);
return rval;
}
-struct shared_network *new_shared_network (name)
+struct shared_network *new_shared_network(name)
char *name;
{
struct shared_network *rval =
- dmalloc (sizeof (struct shared_network), name);
+ dmalloc (sizeof(struct shared_network), name);
return rval;
}
-struct group *new_group (name)
+struct group *new_group(name)
char *name;
{
struct group *rval =
- dmalloc (sizeof (struct group), name);
+ dmalloc(sizeof(struct group), name);
return rval;
}
-struct protocol *new_protocol (name)
+struct protocol *new_protocol(name)
char *name;
{
- struct protocol *rval = dmalloc (sizeof (struct protocol), name);
+ struct protocol *rval = dmalloc(sizeof(struct protocol), name);
return rval;
}
@@ -198,7 +202,7 @@ struct lease_state *new_lease_state (name)
if (free_lease_states) {
rval = free_lease_states;
free_lease_states =
- (struct lease_state *)(free_lease_states -> next);
+ (struct lease_state *)(free_lease_states->next);
} else {
rval = dmalloc (sizeof (struct lease_state), name);
}
@@ -225,21 +229,23 @@ void free_name_server (ptr, name)
struct name_server *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_domain_search_list (ptr, name)
struct domain_search_list *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_lease_state (ptr, name)
struct lease_state *ptr;
char *name;
{
- ptr -> next = free_lease_states;
+ if (ptr->prl)
+ dfree (ptr->prl, name);
+ ptr->next = free_lease_states;
free_lease_states = ptr;
}
@@ -247,63 +253,63 @@ void free_protocol (ptr, name)
struct protocol *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_group (ptr, name)
struct group *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_shared_network (ptr, name)
struct shared_network *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_class (ptr, name)
struct class *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_subnet (ptr, name)
struct subnet *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_lease (ptr, name)
struct lease *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_hash_bucket (ptr, name)
struct hash_bucket *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_hash_table (ptr, name)
struct hash_table *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_tree_cache (ptr, name)
struct tree_cache *ptr;
char *name;
{
- ptr -> value = (unsigned char *)free_tree_caches;
+ ptr->value = (unsigned char *)free_tree_caches;
free_tree_caches = ptr;
}
@@ -311,19 +317,26 @@ void free_packet (ptr, name)
struct packet *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_dhcp_packet (ptr, name)
struct dhcp_packet *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
}
void free_tree (ptr, name)
struct tree *ptr;
char *name;
{
- dfree ((VOIDPTR)ptr, name);
+ dfree (ptr, name);
+}
+
+void free_string_list (ptr, name)
+ struct string_list *ptr;
+ char *name;
+{
+ dfree (ptr, name);
}
diff --git a/usr.sbin/dhcp/common/bpf.c b/usr.sbin/dhcp/common/bpf.c
index cc248613716..2509299291d 100644
--- a/usr.sbin/dhcp/common/bpf.c
+++ b/usr.sbin/dhcp/common/bpf.c
@@ -3,8 +3,8 @@
BPF socket interface code, originally contributed by Archie Cobbs. */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
+ * 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
@@ -40,41 +40,28 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: bpf.c,v 1.2 2001/01/03 16:04:38 ericj Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
-#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
#include <sys/ioctl.h>
#include <sys/uio.h>
-
#include <net/bpf.h>
-#ifdef NEED_OSF_PFILT_HACKS
-#include <net/pfilt.h>
-#endif
+
#include <netinet/in_systm.h>
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <netinet/if_ether.h>
/* Reinitializes the specified interface after an address change. This
is not required for packet-filter APIs. */
-#ifdef USE_BPF_SEND
void if_reinitialize_send (info)
struct interface_info *info;
{
}
-#endif
-#ifdef USE_BPF_RECEIVE
void if_reinitialize_receive (info)
struct interface_info *info;
{
}
-#endif
/* Called by get_interface_list for each interface that's discovered.
Opens a packet filter for each interface and adds it to the select
@@ -89,16 +76,17 @@ int if_register_bpf (info)
/* Open a BPF device */
for (b = 0; 1; b++) {
-#ifndef NO_SNPRINTF
snprintf(filename, sizeof(filename), BPF_FORMAT, b);
-#else
- sprintf(filename, BPF_FORMAT, b);
-#endif
sock = open (filename, O_RDWR, 0);
if (sock < 0) {
if (errno == EBUSY) {
continue;
} else {
+ if (!b)
+ error ("No bpf devices.%s%s%s",
+ " Please read the README",
+ " section for your operating",
+ " system.");
error ("Can't find free bpf: %m");
}
} else {
@@ -113,36 +101,31 @@ int if_register_bpf (info)
return sock;
}
-#endif /* USE_BPF_SEND || USE_BPF_RECEIVE */
-#ifdef USE_BPF_SEND
void if_register_send (info)
struct interface_info *info;
{
/* If we're using the bpf API for sending and receiving,
we don't need to register this interface twice. */
-#ifndef USE_BPF_RECEIVE
- info -> wfdesc = if_register_bpf (info, interface);
-#else
+
info -> wfdesc = info -> rfdesc;
-#endif
+
if (!quiet_interface_discovery)
- note ("Sending on BPF/%s/%s/%s",
+ note ("Sending on BPF/%s/%s%s%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
+ (info -> shared_network ? "/" : ""),
(info -> shared_network ?
- info -> shared_network -> name : "unattached"));
+ info -> shared_network -> name : ""));
}
-#endif /* USE_BPF_SEND */
-#ifdef USE_BPF_RECEIVE
/* 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! XXX */
-struct bpf_insn filter [] = {
+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),
@@ -169,6 +152,22 @@ struct bpf_insn filter [] = {
BPF_STMT(BPF_RET+BPF_K, 0),
};
+int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
+
+struct bpf_insn dhcp_bpf_tr_filter [] = {
+ /* accept all token ring packets due to variable length header */
+ /* if we want to get clever, insert the program here */
+
+ /* 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_tr_filter_len = (sizeof dhcp_bpf_tr_filter /
+ sizeof (struct bpf_insn));
+
void if_register_receive (info)
struct interface_info *info;
{
@@ -193,21 +192,6 @@ void if_register_receive (info)
if (ioctl (info -> rfdesc, BIOCIMMEDIATE, &flag) < 0)
error ("Can't set immediate mode on bpf device: %m");
-#ifdef NEED_OSF_PFILT_HACKS
- /* Allow the copyall flag to be set... */
- if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
- error ("Can't set ALLOWCOPYALL: %m");
-
- /* Clear all the packet filter mode bits first... */
- bits = 0;
- if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
- error ("Can't clear pfilt bits: %m");
-
- /* Set the ENBATCH, ENCOPYALL, ENBPFHDR bits... */
- bits = ENBATCH | ENCOPYALL | ENBPFHDR;
- if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
- error ("Can't set ENBATCH|ENCOPYALL|ENBPFHDR: %m");
-#endif
/* Get the required BPF buffer length from the kernel. */
if (ioctl (info -> rfdesc, BIOCGBLEN, &info -> rbuf_max) < 0)
error ("Can't get bpf buffer length: %m");
@@ -218,28 +202,28 @@ void if_register_receive (info)
info -> rbuf_len = 0;
/* Set up the bpf filter program structure. */
- p.bf_len = sizeof filter / sizeof (struct bpf_insn);
- p.bf_insns = filter;
+ 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! XXX */
- filter [8].k = ntohs (local_port);
+ dhcp_bpf_filter [8].k = ntohs (local_port);
if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
error ("Can't install packet filter program: %m");
if (!quiet_interface_discovery)
- note ("Listening on BPF/%s/%s/%s",
+ note ("Listening on BPF/%s/%s%s%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
+ (info -> shared_network ? "/" : ""),
(info -> shared_network ?
- info -> shared_network -> name : "unattached"));
+ info -> shared_network -> name : ""));
}
-#endif /* USE_BPF_RECEIVE */
-#ifdef USE_BPF_SEND
+
ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct interface_info *interface;
struct packet *packet;
@@ -252,6 +236,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
int bufp = 0;
unsigned char buf [256];
struct iovec iov [2];
+ int result;
+
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
/* Assemble the headers... */
assemble_hw_header (interface, buf, &bufp, hto);
@@ -265,11 +254,12 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
- return writev(interface -> wfdesc, iov, 2);
+ result = writev(interface -> wfdesc, iov, 2);
+ if (result < 0)
+ warn ("send_packet: %m");
+ return result;
}
-#endif /* USE_BPF_SEND */
-#ifdef USE_BPF_RECEIVE
ssize_t receive_packet (interface, buf, len, from, hfrom)
struct interface_info *interface;
unsigned char *buf;
@@ -381,4 +371,25 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
} while (!length);
return 0;
}
-#endif
+
+int can_unicast_without_arp ()
+{
+ return 1;
+}
+
+int can_receive_unicast_unconfigured (ip)
+ struct interface_info *ip;
+{
+ return 1;
+}
+
+void maybe_setup_fallback ()
+{
+ struct interface_info *fbi;
+ fbi = setup_fallback ();
+ if (fbi) {
+ if_register_fallback (fbi);
+ add_protocol ("fallback", fallback_interface -> wfdesc,
+ fallback_discard, fallback_interface);
+ }
+}
diff --git a/usr.sbin/dhcp/common/conflex.c b/usr.sbin/dhcp/common/conflex.c
index 4855a973400..58136a2bc1a 100644
--- a/usr.sbin/dhcp/common/conflex.c
+++ b/usr.sbin/dhcp/common/conflex.c
@@ -40,11 +40,6 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: conflex.c,v 1.1 1998/08/18 03:43:25 deraadt Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
#include "dhctoken.h"
#include <ctype.h>
@@ -136,19 +131,10 @@ static int get_token (cfile)
u = ugflag;
c = get_char (cfile);
-#ifdef OLD_LEXER
- if (c == '\n' && p == 1 && !u
- && comment_index < sizeof comments)
- comments [comment_index++] = '\n';
-#endif
if (!(c == '\n' && eol_token) && isascii (c) && isspace (c))
continue;
if (c == '#') {
-#ifdef OLD_LEXER
- if (comment_index < sizeof comments)
- comments [comment_index++] = '#';
-#endif
skip_to_eol (cfile);
continue;
}
@@ -237,13 +223,8 @@ static void skip_to_eol (cfile)
c = get_char (cfile);
if (c == EOF)
return;
-#ifdef OLD_LEXER
- if (comment_index < sizeof (comments))
- comments [comment_index++] = c;
-#endif
- if (c == EOL) {
+ if (c == EOL)
return;
- }
} while (1);
}
@@ -294,13 +275,6 @@ static int read_number (c, cfile)
c = get_char (cfile);
if (!seenx && c == 'x') {
seenx = 1;
-#ifndef OLD_LEXER
- } else if (isascii (c) && !isxdigit (c) &&
- (c == '-' || c == '_' || isalpha (c))) {
- token = NAME;
- } else if (isascii (c) && !isdigit (c) && isxdigit (c)) {
- token = NUMBER_OR_NAME;
-#endif
} else if (!isascii (c) || !isxdigit (c)) {
ungetc (c, cfile);
ugflag = 1;
@@ -354,6 +328,8 @@ static int intern (atom, 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"))
@@ -362,6 +338,8 @@ static int intern (atom, dfv)
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"))
@@ -417,6 +395,8 @@ static int intern (atom, dfv)
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"))
@@ -462,6 +442,8 @@ static int intern (atom, dfv)
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"))
@@ -526,12 +508,18 @@ static int intern (atom, dfv)
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, "ser-class"))
- return USER_CLASS;
- if (!strcasecmp (atom + 1, "se-host-decl-names"))
- return USE_HOST_DECL_NAMES;
if (!strcasecmp (atom + 1, "nknown-clients"))
return UNKNOWN_CLIENTS;
break;
diff --git a/usr.sbin/dhcp/common/convert.c b/usr.sbin/dhcp/common/convert.c
index 60db34258d9..c08e9d3a09f 100644
--- a/usr.sbin/dhcp/common/convert.c
+++ b/usr.sbin/dhcp/common/convert.c
@@ -41,11 +41,6 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: convert.c,v 1.1 1998/08/18 03:43:25 deraadt Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
u_int32_t getULong (buf)
@@ -102,7 +97,7 @@ void putLong (obuf, val)
void putUShort (obuf, val)
unsigned char *obuf;
- u_int16_t val;
+ unsigned int val;
{
u_int16_t tmp = htons (val);
memcpy (obuf, &tmp, sizeof tmp);
@@ -110,7 +105,7 @@ void putUShort (obuf, val)
void putShort (obuf, val)
unsigned char *obuf;
- int16_t val;
+ int val;
{
int16_t tmp = htons (val);
memcpy (obuf, &tmp, sizeof tmp);
diff --git a/usr.sbin/dhcp/common/dhcp-options.5 b/usr.sbin/dhcp/common/dhcp-options.5
index 77eb58db99e..5e7ca000249 100644
--- a/usr.sbin/dhcp/common/dhcp-options.5
+++ b/usr.sbin/dhcp/common/dhcp-options.5
@@ -1,6 +1,6 @@
.\" dhcp-options.5
.\"
-.\" Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
+.\" Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,7 @@
.\" Enterprises, see ``http://www.vix.com''.
.TH dhcpd-options 5
.SH NAME
-dhcp-options - DHCP options
+dhcp-options - Dynamic Host Configuration Protocol options
.SH DESCRIPTION
The Dynamic Host Configuration protocol allows the client to receive
.B options
@@ -68,13 +68,13 @@ domain name resolves to a single IP address.
.PP
The
.B int32
-data type specifies a signed 32-bit integer. The
+data type specifies a signed 32-bit integer. The
.B uint32
-data type specifies an unsigned 32-bit integer. The
+data type specifies an unsigned 32-bit integer. The
.B int16
and
.B uint16
-data types specify signed and unsigned 16-bit integers. The
+data types specify signed and unsigned 16-bit integers. The
.B int8
and
.B uint8
@@ -100,12 +100,12 @@ The
.B data-string
data type specifies either an NVT ASCII string
enclosed in double quotes, or a series of octets specified in
-hexadecimal, separated by colons. For example:
+hexadecimal, seperated by colons. For example:
.nf
.sp 1
- option client-identifier "CLIENT-FOO";
+ option dhcp-client-identifier "CLIENT-FOO";
or
- option client-identifier 43:4c:49:45:54:2d:46:4f:4f;
+ option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
.fi
.PP
The documentation for the various options mentioned below is taken
@@ -113,7 +113,7 @@ from the latest IETF draft document on DHCP options. Options which
are not listed by name may be defined by the name option-\fInnn\fR,
where \fInnn\fI 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
+a series of octets, expressed as two-digit hexadecimal numbers seperated
by colons. For example:
.PP
.nf
@@ -126,7 +126,8 @@ no checking is done to ensure the correctness of the entered data.
.PP
The standard options are:
.PP
- \fBoption subnet-mask\fR \fIip-address\fR\fB;\fR
+.B option subnet-mask \fIip-address\fR\fB;\fR
+.RS 0.25i
.PP
The 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
@@ -136,114 +137,162 @@ for the network on which an address is being assigned. However,
subnet-mask option declaration that is in scope for the address being
assigned will override the subnet mask specified in the subnet
declaration.
+.RE
.PP
- \fBoption time-offset\fR \fIint32\fR\fB;\fR
+.B option time-offset \fIint32\fR\fB;\fR
+.RS 0.25i
.PP
The time-offset option specifies the offset of the client's subnet in
seconds from Coordinated Universal Time (UTC).
+.RE
.PP
- \fBoption routers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option routers \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The routers option specifies a list of IP addresses for routers on the
client's subnet. Routers should be listed in order of preference.
+.RE
.PP
- \fBoption time-servers\fR \fIip-address [, \fIip-address\fR ... ]\fB;\fR
+.B option time-servers \fIip-address\fR [, \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The time-server option specifies a list of RFC 868 time servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBien116-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ];
+.B option \fBien116-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+];
+.RS 0.25i
.PP
The ien116-name-servers option specifies a list of IEN 116 name servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBdomain-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBdomain-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The 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.
+.RE
.PP
- \fBoption\fR \fBlog-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBlog-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The log-server option specifies a list of MIT-LCS UDP log servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBcookie-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBcookie-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The cookie server option specifies a list of RFC 865 cookie
servers available to the client. Servers should be listed in order
of preference.
+.RE
.PP
- \fBoption\fR \fBlpr-servers\fR \fIip-address \fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBlpr-servers\fR \fIip-address \fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The LPR server option specifies a list of RFC 1179 line printer
servers available to the client. Servers should be listed in order
of preference.
+.RE
.PP
- \fBoption\fR \fBimpress-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBimpress-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The impress-server option specifies a list of Imagen Impress servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBresource-location-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBresource-location-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of RFC 887 Resource Location
servers available to the client. Servers should be listed in order
of preference.
+.RE
.PP
- \fBoption\fR \fBhost-name\fR \fIstring\fR\fB;\fR
+.B option \fBhost-name\fR \fIstring\fR\fB;\fR
+.RS 0.25i
.PP
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 domain-name option to specify the domain name). See RFC 1035 for
character set restrictions.
+.RE
.PP
- \fBoption\fR \fBboot-size\fR \fIuint16\fR\fB;\fR
+.B option \fBboot-size\fR \fIuint16\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the length in 512-octet blocks of the default
boot image for the client.
+.RE
.PP
- \fBoption\fR \fBmerit-dump\fR \fIstring\fR\fB;\fR
+.B option \fBmerit-dump\fR \fIstring\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the path-name 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 NVT ASCII character set.
+.RE
.PP
- \fBoption\fR \fBdomain-name\fR \fIstring\fR\fB;\fR
+.B option \fBdomain-name\fR \fIstring\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the domain name that client should use when
resolving hostnames via the Domain Name System.
+.RE
.PP
- \fBoption\fR \fBswap-server\fR \fIip-address\fR\fB;\fR
+.B option \fBswap-server\fR \fIip-address\fR\fB;\fR
+.RS 0.25i
.PP
This specifies the IP address of the client's swap server.
+.RE
.PP
- \fBoption\fR \fBroot-path\fR \fIstring\fB;\fR\fR
+.B option \fBroot-path\fR \fIstring\fB;\fR\fR
+.RS 0.25i
.PP
This option specifies the path-name that contains the client's root
disk. The path is formatted as a character string consisting of
characters from the NVT ASCII character set.
+.RE
.PP
- \fBoption\fR \fBip-forwarding\fR \fIflag\fR\fB;\fR
+.B option \fBip-forwarding\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBnon-local-source-routing\fR \fIflag\fR\fB;\fR
+.B option \fBnon-local-source-routing\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBpolicy-filter\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR ... ]\fB;\fR
+.B option \fBpolicy-filter\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies policy filters for non-local source routing.
The filters consist of a list of IP addresses and masks which specify
@@ -253,36 +302,49 @@ 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 (RFC1122) for further information.
+.RE
.PP
- \fBoption\fR \fBmax-dgram-reassembly\fR \fIuint16\fR\fB;\fR
+.B option \fBmax-dgram-reassembly\fR \fIuint16\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the maximum size datagram that the client
should be prepared to reassemble. The minimum value legal value is
576.
+.RE
.PP
- \fBoption\fR \fBdefault-ip-ttl\fR \fIuint8;\fR
+.B option \fBdefault-ip-ttl\fR \fIuint8;\fR
+.RS 0.25i
.PP
This option specifies the default time-to-live that the client should
use on outgoing datagrams.
+.RE
.PP
- \fBoption\fR \fBpath-mtu-aging-timeout\fR \fIuint32\fR\fB;\fR
+.B option \fBpath-mtu-aging-timeout\fR \fIuint32\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the timeout (in seconds) to use when aging Path
MTU values discovered by the mechanism defined in RFC 1191.
+.RE
.PP
- \fBoption\fR \fBpath-mtu-plateau-table\fR \fIuint16\fR [\fB,\fR \fIuint16\fR ... ]\fB;\fR
+.B option \fBpath-mtu-plateau-table\fR \fIuint16\fR [\fB,\fR \fIuint16\fR...
+]\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBinterface-mtu\fR \fIuint16\fR\fB;\fR
+.B option \fBinterface-mtu\fR \fIuint16\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the MTU to use on this interface. The minimum
legal value for the MTU is 68.
+.RE
.PP
- \fBoption\fR \fBall-subnets-local\fR \fIflag\fR\fB;\fR
+.B option \fBall-subnets-local\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
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
@@ -290,41 +352,54 @@ 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.
+.RE
.PP
- \fBoption\fR \fBbroadcast-address\fR \fIip-address\fR\fB;\fR
+.B option \fBbroadcast-address\fR \fIip-address\fR\fB;\fR
+.RS 0.25i
.PP
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 (RFC1122).
+.RE
.PP
- \fBoption\fR \fBperform-mask-discovery\fR \fIflag\fR\fB;\fR
+.B option \fBperform-mask-discovery\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBmask-supplier\fR \fIflag\fR\fB;\fR
+.B option \fBmask-supplier\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBrouter-discovery\fR \fIflag\fR\fB;\fR
+.B option \fBrouter-discovery\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBrouter-solicitation-address\fR \fIip-address\fR\fB;\fR
+.B option \fBrouter-solicitation-address\fR \fIip-address\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the address to which the client should transmit
router solicitation requests.
+.RE
.PP
- \fBoption\fR \fBstatic-routes\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR ... ]\fB;\fR
+.B option \fBstatic-routes\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of static routes that the client should
install in its routing cache. If multiple routes to the same
@@ -339,106 +414,270 @@ The default route (0.0.0.0) is an illegal destination for a static
route. To specify the default route, use the
.B routers
option.
+.RE
.PP
- \fBoption\fR \fBtrailer-encapsulation\fR \fIflag\fR\fB;\fR
+.B option \fBtrailer-encapsulation\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBarp-cache-timeout\fR \fIuint32\fR\fB;\fR
+.B option \fBarp-cache-timeout\fR \fIuint32\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the timeout in seconds for ARP cache entries.
+.RE
.PP
- \fBoption\fR \fBieee802-3-encapsulation\fR \fIflag\fR\fB;\fR
+.B option \fBieee802-3-encapsulation\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBdefault-tcp-ttl\fR \fIuint8\fR\fB;\fR
+.B option \fBdefault-tcp-ttl\fR \fIuint8\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the default TTL that the client should use when
sending TCP segments. The minimum value is 1.
+.RE
.PP
- \fBoption\fR \fBtcp-keepalive-interval\fR \fIuint32\fR\fB;\fR
+.B option \fBtcp-keepalive-interval\fR \fIuint32\fR\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBtcp-keepalive-garbage\fR \fIflag\fR\fB;\fR
+.B option \fBtcp-keepalive-garbage\fR \fIflag\fR\fB;\fR
+.RS 0.25i
.PP
This option specifies the whether or not the client should send TCP
keepalive messages with a 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.
+.RE
.PP
- \fBoption\fR \fBnis-domain\fR \fIstring\fR\fB;\fR
+.B option \fBnis-domain\fR \fIstring\fR\fB;\fR
+.RS 0.25i
.PP
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 NVT ASCII character set.
+.RE
.PP
- \fBoption\fR \fBnis-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBnis-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of IP addresses indicating NIS servers
available to the client. Servers should be listed in order of
preference.
+.RE
.PP
- \fBoption\fR \fBntp-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBntp-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBnetbios-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBnetbios-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The NetBIOS name server (NBNS) option specifies a list of RFC
-1001/1002 NBNS name servers listed in order of preference.
+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 netbios-name-servers option.
+.RE
.PP
- \fBoption\fR \fBnetbios-dd-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBnetbios-dd-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
The NetBIOS datagram distribution server (NBDD) option specifies a
list of RFC 1001/1002 NBDD servers listed in order of preference.
+.RE
.PP
- \fBoption\fR \fBnetbios-node-type\fR \fIuint8\fR\fB;\fR
+.B option \fBnetbios-node-type\fR \fIuint8\fR\fB;\fR
+.RS 0.25i
.PP
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.
-A value of 1 corresponds to a NetBIOS B-node; a value of 2 corresponds
-to a P-node; a value of 4 corresponds to an M-node; a value of 8
-corresponds to an H-node.
.PP
- \fBoption\fR \fBnetbios-scope\fR \fIstring\fR\fB;\fR
+Possible node types are:
+.PP
+.TP 5
+.I 1
+B-node: Broadcast - no WINS
+.TP
+.I 2
+P-node: Peer - WINS only.
+.TP
+.I 4
+M-node: Mixed - broadcast, then WINS
+.TP
+.I 8
+H-node: Hybrid - WINS, then broadcast
+.RE
+.PP
+.B option
+.B netbios-scope
+.I string\fB;\fR
+.RS 0.25i
.PP
The NetBIOS scope option specifies the NetBIOS over TCP/IP scope
parameter for the client as specified in RFC 1001/1002. See RFC1001,
RFC1002, and RFC1035 for character-set restrictions.
+.RE
.PP
- \fBoption\fR \fBfont-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBfont-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
This option specifies a list of X Window System Font servers available
to the client. Servers should be listed in order of preference.
+.RE
.PP
- \fBoption\fR \fBx-display-manager\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
+.B option \fBx-display-manager\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
.PP
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.
+.RE
.PP
- \fBoption\fR \fBdhcp-client-identifier\fR \fIdata-string\fR\fB;\fR
+.B option \fBdhcp-client-identifier\fR \fIdata-string\fR\fB;\fR
+.RS 0.25i
.PP
This option can be used to specify the a DHCP client identifier in a
host declaration, so that dhcpd can find the host record by matching
against the client identifier.
+.RE
+.B option \fBnisplus-domain\fR \fIstring\fR\fB;\fR
+.RS 0.25i
+.PP
+This option specifies the name of the client's NIS+ domain. The
+domain is formatted as a character string consisting of characters
+from the NVT ASCII character set.
+.RE
+.B option \fBnisplus-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
+]\fB;\fR
+.RS 0.25i
+.PP
+This option specifies a list of IP addresses indicating NIS+ servers
+available to the client. Servers should be listed in order of
+preference.
+.RE
+.PP
+.B option \fBtftp-server-name\fR \fIstring\fR\fB;\fR
+.RS 0.25i
+.PP
+This option is used to identify a TFTP server and, if supported by the
+client, should have the same effect as the \fBserver-name\fR
+declaration. BOOTP clients are unlikely to support this option.
+Some DHCP clients will support it, and others actually require it.
+.RE
+.PP
+.B option \fBbootfile-name\fR \fIstring\fR\fB;\fR
+.RS 0.25i
+.PP
+This option is used to identify a bootstrap file. If supported by the
+client, it should have the same effect as the \fBfilename\fR
+declaration. BOOTP clients are unlikely to support this option. Some
+DHCP clients will support it, and others actually require it.
+.RE
+.PP
+.B option \fBmobile-ip-home-agent\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+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.
+.RE
+.PP
+.B option \fBsmtp-server\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+The SMTP server option specifies a list of SMTP servers available to
+the client. Servers should be listed in order of preference.
+.RE
+.PP
+.B option \fBpop-server\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+The POP3 server option specifies a list of POP3 available to the
+client. Servers should be listed in order of preference.
+.RE
+.PP
+.B option \fBnntp-server\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+The NNTP server option specifies a list of NNTP available to the
+client. Servers should be listed in order of preference.
+.RE
+.PP
+.B option \fBwww-server\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+The WWW server option specifies a list of WWW available to the
+client. Servers should be listed in order of preference.
+.RE
+.PP
+.B option \fBfinger-server\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+The Finger server option specifies a list of Finger available to the
+client. Servers should be listed in order of preference.
+.RE
+.PP
+.B option \fBirc-server\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+The IRC server option specifies a list of IRC available to the
+client. Servers should be listed in order of preference.
+.RE
+.PP
+.B option \fBstreettalk-server\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+The StreetTalk server option specifies a list of StreetTalk servers
+available to the client. Servers should be listed in order of
+preference.
+.RE
+.PP
+.B option \fBstreetalk-directory-assistance-server\fR \fIip-address\fR [\fB,\fR
+\fIip-address\fR... ]\fB;\fR
+.RS 0.25i
+.PP
+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.
+.RE
.SH SEE ALSO
dhcpd.conf(5), dhcpd.leases(5), dhclient.conf(5), dhcpd(8),
dhclient(8), RFC2132, RFC2131.
diff --git a/usr.sbin/dhcp/common/dispatch.c b/usr.sbin/dhcp/common/dispatch.c
index 5470e19e758..3e1aff476e1 100644
--- a/usr.sbin/dhcp/common/dispatch.c
+++ b/usr.sbin/dhcp/common/dispatch.c
@@ -3,8 +3,8 @@
Network input dispatcher... */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
+ * 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
@@ -40,29 +40,26 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: dispatch.c,v 1.4 2001/01/03 16:04:38 ericj Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
#include <sys/ioctl.h>
+#include <poll.h>
#include <net/if_media.h>
+
/* Most boxes has less than 16 interfaces, so this might be a good guess. */
#define INITIAL_IFREQ_COUNT 16
-struct interface_info *interfaces, *dummy_interfaces;
+struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
struct protocol *protocols;
struct timeout *timeouts;
static struct timeout *free_timeouts;
static int interfaces_invalidated;
void (*bootp_packet_handler) PROTO ((struct interface_info *,
- unsigned char *, int, unsigned short,
+ struct dhcp_packet *, int, unsigned int,
struct iaddr, struct hardware *));
-int interface_status PROTO((struct interface_info *));
-static void got_one PROTO ((struct protocol *));
+static int interface_status(struct interface_info *ifinfo);
+
int quiet_interface_discovery;
/* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces.
@@ -85,12 +82,10 @@ void discover_interfaces (state)
struct shared_network *share;
struct sockaddr_in foo;
int ir;
+ struct ifreq *tif;
#ifdef ALIAS_NAMES_PERMUTED
char *s;
#endif
-#ifdef USE_FALLBACK
- static struct shared_network fallback_network;
-#endif
/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
@@ -133,37 +128,17 @@ void discover_interfaces (state)
else
ir = INTERFACE_REQUESTED;
- /* Cycle through the list of interfaces looking for IP addresses.
- Go through twice; once to count the number of addresses, and a
- second time to copy them into an array of addresses. */
+ /* Cycle through the list of interfaces looking for IP addresses. */
for (i = 0; i < ic.ifc_len;) {
struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
-#ifdef HAVE_SA_LEN
- if (ifp -> ifr_addr.sa_len)
- i += ((sizeof ifp -> ifr_name) +
- (ifp -> ifr_addr.sa_len >
- sizeof (struct sockaddr) ?
- ifp -> ifr_addr.sa_len :
- sizeof (struct sockaddr)));
+ if (ifp -> ifr_addr.sa_len > sizeof (struct sockaddr))
+ i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
else
-#endif
i += sizeof *ifp;
-#ifdef ALIAS_NAMES_PERMUTED
- if ((s = strrchr (ifp -> ifr_name, ':'))) {
- *s = 0;
- }
-#endif
-
-#ifdef SKIP_DUMMY_INTERFACES
- if (!strncmp (ifp -> ifr_name, "dummy", 5))
- continue;
-#endif
-
-
/* See if this is the sort of interface we want to
deal with. */
- strlcpy (ifr.ifr_name, ifp -> ifr_name, sizeof(ifr.ifr_name));
+ strlcpy (ifr.ifr_name, ifp -> ifr_name, IFNAMSIZ);
if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
error ("Can't get interface flags for %s: %m",
ifr.ifr_name);
@@ -172,9 +147,7 @@ void discover_interfaces (state)
except don't skip down interfaces if we're trying to
get a list of configurable interfaces. */
if ((ifr.ifr_flags & IFF_LOOPBACK) ||
-#ifdef IFF_POINTOPOINT
(ifr.ifr_flags & IFF_POINTOPOINT) ||
-#endif
(!(ifr.ifr_flags & IFF_UP) &&
state != DISCOVER_UNCONFIGURED))
continue;
@@ -192,17 +165,14 @@ void discover_interfaces (state)
if (!tmp)
error ("Insufficient memory to %s %s",
"record interface", ifp -> ifr_name);
- strlcpy (tmp -> name, ifp -> ifr_name,
- sizeof(tmp->name));
+ strlcpy (tmp -> name, ifp -> ifr_name, IFNAMSIZ);
tmp -> next = interfaces;
tmp -> flags = ir;
- tmp -> noifmedia = tmp -> dead = tmp->errors = 0;
interfaces = tmp;
}
/* If we have the capability, extract link information
and record it in a linked list. */
-#ifdef AF_LINK
if (ifp -> ifr_addr.sa_family == AF_LINK) {
struct sockaddr_dl *foo = ((struct sockaddr_dl *)
(&ifp -> ifr_addr));
@@ -211,64 +181,10 @@ void discover_interfaces (state)
memcpy (tmp -> hw_address.haddr,
LLADDR (foo), foo -> sdl_alen);
} else
-#endif /* AF_LINK */
if (ifp -> ifr_addr.sa_family == AF_INET) {
struct iaddr addr;
-#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
- struct ifreq ifr;
- struct sockaddr sa;
- int b, sk;
-
- /* Read the hardware address from this interface. */
- ifr = *ifp;
- if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
- error ("Can't get hardware address for %s: %m",
- ifr.ifr_name);
-
- sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
-
- switch (sa.sa_family) {
-#ifdef ARPHRD_LOOPBACK
- case ARPHRD_LOOPBACK:
- /* ignore loopback interface */
- break;
-#endif
-
- case ARPHRD_ETHER:
- tmp -> hw_address.hlen = 6;
- tmp -> hw_address.htype = ARPHRD_ETHER;
- memcpy (tmp -> hw_address.haddr,
- sa.sa_data, 6);
- break;
-
-#ifndef ARPHRD_IEEE802
-# define ARPHRD_IEEE802 HTYPE_IEEE802
-#endif
- case ARPHRD_IEEE802:
- tmp -> hw_address.hlen = 6;
- tmp -> hw_address.htype = ARPHRD_IEEE802;
- memcpy (tmp -> hw_address.haddr,
- sa.sa_data, 6);
- break;
-
-#ifdef ARPHRD_METRICOM
- case ARPHRD_METRICOM:
- tmp -> hw_address.hlen = 6;
- tmp -> hw_address.htype = ARPHRD_METRICOM;
- memcpy (tmp -> hw_address.haddr,
- sa.sa_data, 6);
-
- break;
-#endif
-
- default:
- error ("%s: unknown hardware address type %d",
- ifr.ifr_name, sa.sa_family);
- }
-#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
-
/* Get a pointer to the address... */
memcpy (&foo, &ifp -> ifr_addr,
sizeof ifp -> ifr_addr);
@@ -282,13 +198,8 @@ void discover_interfaces (state)
found, keep a pointer to ifreq structure in
which we found it. */
if (!tmp -> ifp) {
- struct ifreq *tif;
-#ifdef HAVE_SA_LEN
int len = ((sizeof ifp -> ifr_name) +
ifp -> ifr_addr.sa_len);
-#else
- int len = sizeof *ifp;
-#endif
tif = (struct ifreq *)malloc (len);
if (!tif)
error ("no space to remember ifp.");
@@ -341,6 +252,9 @@ void discover_interfaces (state)
}
}
+ /* Now cycle through all the interfaces we found, looking for
+ hardware addresses. */
+
/* If we're just trying to get a list of interfaces that we might
be able to configure, we can quit now. */
if (state == DISCOVER_UNCONFIGURED)
@@ -374,9 +288,14 @@ void discover_interfaces (state)
sizeof tmp -> ifp -> ifr_addr);
/* We must have a subnet declaration for each interface. */
- if (!tmp -> shared_network && (state == DISCOVER_SERVER))
- error ("No subnet declaration for %s (%s).",
- tmp -> name, inet_ntoa (foo.sin_addr));
+ if (!tmp -> shared_network && (state == DISCOVER_SERVER)) {
+ warn ("No subnet declaration for %s (%s).",
+ tmp -> name, inet_ntoa (foo.sin_addr));
+ warn ("Please write a subnet declaration in your %s",
+ "dhcpd.conf file for the");
+ error ("network segment to which interface %s %s",
+ tmp -> name, "is attached.");
+ }
/* Find subnets that don't have valid interface
addresses... */
@@ -404,14 +323,26 @@ void discover_interfaces (state)
close (sock);
-#ifdef USE_FALLBACK
- strlcpy (fallback_interface.name, "fallback", sizeof(fallback_interface.name));
- fallback_interface.shared_network = &fallback_network;
- fallback_network.name = "fallback-net";
- if_register_fallback (&fallback_interface);
- add_protocol ("fallback", fallback_interface.wfdesc,
- fallback_discard, &fallback_interface);
-#endif
+ maybe_setup_fallback ();
+}
+
+struct interface_info *setup_fallback ()
+{
+ fallback_interface =
+ ((struct interface_info *)
+ dmalloc (sizeof *fallback_interface, "discover_interfaces"));
+ if (!fallback_interface)
+ error ("Insufficient memory to record fallback interface.");
+ memset (fallback_interface, 0, sizeof *fallback_interface);
+ strlcpy (fallback_interface -> name, "fallback", IFNAMSIZ);
+ fallback_interface -> shared_network =
+ new_shared_network ("parse_statement");
+ if (!fallback_interface -> shared_network)
+ error ("No memory for shared subnet");
+ memset (fallback_interface -> shared_network, 0,
+ sizeof (struct shared_network));
+ fallback_interface -> shared_network -> name = "fallback-net";
+ return fallback_interface;
}
void reinitialize_interfaces ()
@@ -423,28 +354,34 @@ void reinitialize_interfaces ()
if_reinitialize_send (ip);
}
-#ifdef USE_FALLBACK
- if_reinitialize_fallback (&fallback_interface);
-#endif
+ if (fallback_interface)
+ if_reinitialize_send (fallback_interface);
interfaces_invalidated = 1;
}
-/* Wait for packets to come in using select(). When one does, call
- receive_packet to receive the packet and possibly strip hardware
- addressing information from it, and then call do_packet to try to
- do something with it. */
+/* 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 ()
{
- fd_set r, w, x;
struct protocol *l;
- int max = 0;
+ int nfds = 0;
+ struct pollfd *fds;
int count;
- struct timeval tv, *tvp;
+ int i;
+ time_t howlong;
+ int to_msec;
- FD_ZERO (&w);
- FD_ZERO (&x);
+ nfds = 0;
+ for (l = protocols; l; l = l -> next) {
+ ++nfds;
+ }
+ fds = (struct pollfd *)malloc ((nfds) * sizeof (struct pollfd));
+ if (fds == NULL)
+ error ("Can't allocate poll structures.");
do {
/* Call any expired timeouts, and then if there's
@@ -461,69 +398,84 @@ void dispatch ()
free_timeouts = t;
goto another;
}
- tv.tv_sec = timeouts -> when - cur_time;
- tv.tv_usec = 0;
- tvp = &tv;
+ /*
+ * 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 indefinetely.
+ */
+
+ howlong = timeouts -> when - cur_time;
+ if (howlong > INT_MAX / 1000)
+ howlong = INT_MAX / 1000;
+ to_msec = howlong * 1000;
} else
- tvp = (struct timeval *)0;
-
- /* Set up the read mask. */
- FD_ZERO (&r);
-
- max = -1;
+ to_msec = -1;
+ /* Set up the descriptors to be polled. */
+ i = 0;
for (l = protocols; l; l = l -> next) {
- struct interface_info *ip = l -> local;
- if (ip && !ip->dead) {
- FD_SET (l -> fd, &r);
- if (l -> fd > max)
- max = l -> fd;
- }
+ struct interface_info *ip = l -> local;
+ if (ip && !ip->dead) {
+ fds [i].fd = l -> fd;
+ fds [i].events = POLLIN;
+ fds [i].revents = 0;
+ ++i;
+ }
}
- if (max == -1)
- error("No interfaces to select on - exiting.");
+ if (i == 0)
+ error("No live interfaces to poll on - exiting.");
/* Wait for a packet or a timeout... XXX */
- count = select (max + 1, &r, &w, &x, tvp);
+ count = poll (fds, nfds, to_msec);
+
+ /* Not likely to be transitory... */
+ if (count == -1) {
+ if (errno == EAGAIN || errno == EINTR) {
+ GET_TIME (&cur_time);
+ continue;
+ }
+ else
+ error ("poll: %m");
+ }
/* Get the current time... */
GET_TIME (&cur_time);
- /* Not likely to be transitory... */
- if (count == -1)
- error ("select: %m");
-
+ i = 0;
for (l = protocols; l; l = l -> next) {
- struct interface_info *ip;
- if (!FD_ISSET (l -> fd, &r))
- continue;
- ip = l->local;
- if (ip && !ip-> dead && l -> handler)
- (*(l -> handler)) (l);
- if (interfaces_invalidated)
- break;
+ if ((fds [i].revents & POLLIN)) {
+ fds [i].revents = 0;
+ if (l -> handler)
+ (*(l -> handler)) (l);
+ if (interfaces_invalidated)
+ break;
+ }
+ ++i;
}
interfaces_invalidated = 0;
} while (1);
}
-static void got_one (l)
+void got_one (l)
struct protocol *l;
{
struct sockaddr_in from;
struct hardware hfrom;
struct iaddr ifrom;
size_t result;
- static unsigned char packbuf [4095]; /* Packet input buffer.
- Must be as large as largest
- possible MTU. */
+ union {
+ unsigned char packbuf [4095]; /* Packet input buffer.
+ Must be as large as largest
+ possible MTU. */
+ struct dhcp_packet packet;
+ } u;
struct interface_info *ip = l -> local;
-
- if ((result = receive_packet (ip, packbuf, sizeof packbuf,
- &from, &hfrom)) == -1) {
+ if ((result =
+ receive_packet (ip, u.packbuf, sizeof u, &from, &hfrom)) == -1) {
warn ("receive_packet failed on %s: %s", ip -> name,
strerror(errno));
ip->errors++;
@@ -544,11 +496,71 @@ static void got_one (l)
ifrom.len = 4;
memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
- (*bootp_packet_handler) (ip, packbuf, result,
+ (*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);
+}
+
int locate_network (packet)
struct packet *packet;
{
@@ -699,70 +711,3 @@ void remove_protocol (proto)
}
}
}
-
-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);
-}
diff --git a/usr.sbin/dhcp/common/dns.c b/usr.sbin/dhcp/common/dns.c
deleted file mode 100644
index 6e2d539dc38..00000000000
--- a/usr.sbin/dhcp/common/dns.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/* dns.c
-
- Domain Name Service subroutines. */
-
-/*
- * Copyright (C) 1992 by Ted Lemon.
- * 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 file is based on software written in 1992 by Ted Lemon for
- * a portable network boot loader. That original code base has been
- * substantially modified for use in the Internet Software Consortium
- * DHCP suite.
- *
- * These later modifications were done on behalf of 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''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: dns.c,v 1.3 2001/01/03 16:04:38 ericj Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "arpa/nameser.h"
-
-int dns_protocol_initialized;
-int dns_protocol_fd;
-
-static int addlabel PROTO ((u_int8_t *, char *));
-static int skipname PROTO ((u_int8_t *));
-static int copy_out_name PROTO ((u_int8_t *, u_int8_t *, char *));
-static int nslookup PROTO ((u_int8_t, char *, int, u_int16_t, u_int16_t));
-static int zonelookup PROTO ((u_int8_t, char *, int, u_int16_t));
-u_int16_t dns_port;
-
-/* Initialize the DNS protocol. */
-
-void dns_startup ()
-{
- struct servent *srv;
-
- /* Only initialize icmp once. */
- if (dns_protocol_initialized)
- error ("attempted to reinitialize dns protocol");
- dns_protocol_initialized = 1;
-
- /* Get the protocol number (should be 1). */
- srv = getservbyname ("domain", "tcp");
- if (srv)
- dns_port = srv -> s_port;
- else
- dns_port = htons (53);
-
- /* Get a socket for the DNS protocol. */
- dns_protocol_fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (!dns_protocol_fd)
- error ("unable to create dns socket: %m");
-
- pick_name_server ();
-
- add_protocol ("dns", dns_protocol_fd, dns_packet, 0);
-}
-
-/* Label manipulation stuff; see RFC1035, page 28 section 4.1.2 and
- page 30, section 4.1.4. */
-
-/* addlabel copies a label into the specified buffer, putting the length of
- the label in the first character, the contents of the label in subsequent
- characters, and returning the length of the conglomeration. */
-
-static int addlabel (buf, label)
- u_int8_t *buf;
- char *label;
-{
- *buf = strlen (label);
- memcpy (buf + 1, label, *buf);
- return *buf + 1;
-}
-
-/* skipname skips over all of the labels in a single domain name,
- returning the length of the domain name. */
-
-static int skipname (label)
- u_int8_t *label;
-{
- if (*label & INDIR_MASK)
- return 2;
- if (*label == 0)
- return 1;
- return *label + 1 + skipname (label + *label + 1);
-}
-
-/* copy_out_name copies out the name appearing at the specified location
- into a string, stored as fields separated by dots rather than lengths
- and labels. The length of the label-formatted name is returned. */
-
-static int copy_out_name (base, name, buf)
- u_int8_t *base;
- u_int8_t *name;
- char *buf;
-{
- if (*name & INDIR_MASK) {
- int offset = (*name & ~INDIR_MASK) + (*name + 1);
- return copy_out_name (base, base + offset, buf);
- }
- if (!*name) {
- *buf = 0;
- return 1;
- }
- memcpy (buf, name + 1, *name);
- *(buf + *name) = '.';
- return (*name + 1
- + copy_out_name (base, name + *name + 1, buf + *name + 1));
-}
-
-/* ns_inaddr_lookup constructs a PTR lookup query for an internet address -
- e.g., 1.200.9.192.in-addr.arpa. If the specified timeout period passes
- before the query is satisfied, or if the query fails, the callback is
- called with a null pointer. Otherwise, the callback is called with the
- address of the string returned by the name server. */
-
-int ns_inaddr_lookup (id, inaddr)
- u_int16_t id;
- struct iaddr inaddr;
-{
- unsigned char namebuf [512];
- unsigned char *s = namebuf;
- unsigned char *label;
- int i;
- unsigned char c;
-
- for (i = 3; i >= 0; --i) {
- label = s++;
- *label = 1;
- c = inaddr.iabuf [i];
- if (c > 100) {
- ++*label;
- *s++ = '0' + c / 100;
- }
- if (c > 10) {
- ++*label;
- *s++ = '0' + ((c / 10) % 10);
- }
- *s++ = '0' + (c % 10);
- }
- s += addlabel (s, "in-addr");
- s += addlabel (s, "arpa");
- *s++ = 0;
-/* return nslookup (id, namebuf, s - namebuf, T_PTR, C_IN); */
- return zonelookup (id, namebuf, s - namebuf, C_IN);
-}
-
-/* Construct and transmit a name server query. */
-
-static int nslookup (id, qname, namelen, qtype, qclass)
- u_int8_t id;
- char *qname;
- int namelen;
- u_int16_t qtype;
- u_int16_t qclass;
-{
- HEADER *hdr;
- unsigned char query [512];
- u_int8_t *s;
- int status;
- struct sockaddr_in *server = pick_name_server ();
-
- if (!server)
- return 0;
-
- /* Construct a header... */
- hdr = (HEADER *)query;
- memset (hdr, 0, sizeof *hdr);
- hdr -> id = htons (id);
- hdr -> rd = 1;
- hdr -> opcode = QUERY;
- hdr -> qdcount = htons (1);
-
- /* Copy in the name we're looking up. */
- s = (u_int8_t *)(hdr + 1);
- memcpy (s, qname, namelen);
- s += namelen;
-
- /* Set the query type. */
- putUShort (s, qtype);
- s += sizeof (u_int16_t);
-
- /* Set the query class. */
- putUShort (s, qclass);
- s += sizeof (u_int16_t);
-
- /* Send the query. */
- status = sendto (dns_protocol_fd, query, s - query, 0,
- (struct sockaddr *)server, sizeof *server);
-
- /* If the send failed, report the failure. */
- if (status < 0)
- return 0;
- return 1;
-}
-
-/* Construct a query for the SOA for a specified name.
- Try every possible SOA name starting from the name specified and going
- to the root name - e.g., for
-
- 215.5.5.192.in-addr.arpa, look for SOAs matching:
-
- 215.5.5.5.192.in-addr.arpa
- 5.5.192.in-addr.arpa
- 5.192.in-addr.arpa
- 192.in-addr.arpa
- in-addr.arpa
- arpa */
-
-static int zonelookup (id, qname, namelen, qclass)
- u_int8_t id;
- char *qname;
- int namelen;
- u_int16_t qclass;
-{
- HEADER *hdr;
- unsigned char query [512];
- u_int8_t *s, *nptr;
- int status, count;
- struct sockaddr_in *server = pick_name_server ();
-
- if (!server)
- return 0;
-
- /* Construct a header... */
- hdr = (HEADER *)query;
- memset (hdr, 0, sizeof *hdr);
- hdr -> id = htons (id);
- hdr -> rd = 1;
- hdr -> opcode = QUERY;
-
- /* Copy in the name we're looking up. */
- s = (u_int8_t *)(hdr + 1);
- memcpy (s, qname, namelen);
- s += namelen;
-
- /* Set the query type. */
- putUShort (s, T_SOA);
- s += sizeof (u_int16_t);
-
- /* Set the query class. */
- putUShort (s, qclass);
- s += sizeof (u_int16_t);
- count = 1;
-
- /* Now query up the hierarchy. */
- nptr = (u_int8_t *)(hdr + 1);
- while (*(nptr += *nptr + 1)) {
- /* Store a compressed reference from the full name. */
- putUShort (s, ntohs (htons (0xC000) |
- htons (nptr - &query [0])));
- s += sizeof (u_int16_t);
-
- /* Store the query type. */
- putUShort (s, T_SOA);
- s += sizeof (u_int16_t);
-
- putUShort (s, qclass);
- s += sizeof (u_int16_t);
-
- /* Increment the query count... */
- ++count;
-break;
- }
- hdr -> qdcount = htons (count);
-
-dump_raw (query, s - query);
- /* Send the query. */
- status = sendto (dns_protocol_fd, query, s - query, 0,
- (struct sockaddr *)server, sizeof *server);
-
- /* If the send failed, report the failure. */
- if (status < 0)
- return 0;
- return 1;
-}
-
-/* Process a reply from a name server. */
-
-void dns_packet (protocol)
- struct protocol *protocol;
-{
- HEADER *ns_header;
- struct sockaddr_in from;
- unsigned char buf [4096];
- unsigned char nbuf [512];
- unsigned char *base;
- unsigned char *dptr;
- u_int16_t type;
- u_int16_t class;
- TIME ttl;
- u_int16_t rdlength;
- int len, status;
- int i;
-
- len = sizeof from;
- status = recvfrom (protocol -> fd, buf, sizeof buf, 0,
- (struct sockaddr *)&from, &len);
- if (status < 0) {
- warn ("icmp_echoreply: %m");
- return;
- }
-
- ns_header = (HEADER *)buf;
- base = (unsigned char *)(ns_header + 1);
-
-#if 0
- /* Ignore invalid packets... */
- if (ntohs (ns_header -> id) > ns_query_max) {
- printf ("Out-of-range NS message; id = %d\n",
- ntohs (ns_header -> id));
- return;
- }
-#endif
-
- /* Parse the response... */
- dptr = base;
-
- /* Skip over the queries... */
- for (i = 0; i < ntohs (ns_header -> qdcount); i++) {
- dptr += skipname (dptr);
- /* Skip over the query type and query class. */
- dptr += 2 * sizeof (u_int16_t);
- }
-
- /* Process the answers... */
- for (i = 0; i < ntohs (ns_header -> ancount); i++) {
- /* Skip over the name we looked up. */
- dptr += skipname (dptr);
-
- /* Get the type. */
- type = getUShort (dptr);
- dptr += sizeof type;
-
- /* Get the class. */
- class = getUShort (dptr);
- dptr += sizeof class;
-
- /* Get the time-to-live. */
- ttl = getULong (dptr);
- dptr += sizeof ttl;
-
- /* Get the length of the reply. */
- rdlength = getUShort (dptr);
- dptr += sizeof rdlength;
-
- switch (type) {
- case T_A:
- note ("A record; value is %d.%d.%d.%d",
- dptr [0], dptr [1], dptr [2], dptr [3]);
- break;
-
- case T_CNAME:
- case T_PTR:
- copy_out_name (base, dptr, nbuf);
- note ("Domain name; value is %s\n", nbuf);
- return;
-
- default:
- note ("unhandled type: %x", type);
- }
- }
-}
diff --git a/usr.sbin/dhcp/common/errwarn.c b/usr.sbin/dhcp/common/errwarn.c
index d370ff612ce..a76e46254df 100644
--- a/usr.sbin/dhcp/common/errwarn.c
+++ b/usr.sbin/dhcp/common/errwarn.c
@@ -40,15 +40,10 @@
* with Vixie Laboratories.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: errwarn.c,v 1.3 2001/01/03 16:04:38 ericj Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
#include <errno.h>
-static void do_percentm PROTO ((char *obuf, char *ibuf));
+static void do_percentm PROTO ((char *obuf, size_t size, char *ibuf));
static char mbuf [1024];
static char fbuf [1024];
@@ -57,20 +52,20 @@ int warnings_occurred;
/* Log an error message, then exit... */
-void error (ANSI_DECL(char *) fmt, VA_DOTDOTDOT)
+void error (char * fmt, ...)
KandR (char *fmt;)
va_dcl
{
va_list list;
- do_percentm (fbuf, fmt);
+ do_percentm (fbuf, sizeof(fbuf), fmt);
- VA_start (list, fmt);
+ 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, mbuf);
#endif
/* Also log it to stderr? */
@@ -90,20 +85,20 @@ void error (ANSI_DECL(char *) fmt, VA_DOTDOTDOT)
/* Log a warning message... */
-int warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+int warn (char * fmt, ...)
KandR (char *fmt;)
va_dcl
{
va_list list;
- do_percentm (fbuf, fmt);
+ do_percentm (fbuf, sizeof(fbuf), fmt);
- VA_start (list, fmt);
+ 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, mbuf);
#endif
if (log_perror) {
@@ -116,20 +111,20 @@ int warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
/* Log a note... */
-int note (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+int note (char * fmt, ...)
KandR (char *fmt;)
va_dcl
{
va_list list;
- do_percentm (fbuf, fmt);
+ do_percentm (fbuf, sizeof(fbuf), fmt);
- VA_start (list, fmt);
+ va_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
- syslog (log_priority | LOG_INFO, "%s", mbuf);
+ syslog (log_priority | LOG_INFO, mbuf);
#endif
if (log_perror) {
@@ -142,20 +137,20 @@ int note (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
/* Log a debug message... */
-int debug (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+int debug (char * fmt, ...)
KandR (char *fmt;)
va_dcl
{
va_list list;
- do_percentm (fbuf, fmt);
+ do_percentm (fbuf, sizeof(fbuf), fmt);
- VA_start (list, fmt);
+ va_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
- syslog (log_priority | LOG_DEBUG, "%s", mbuf);
+ syslog (log_priority | LOG_DEBUG, mbuf);
#endif
if (log_perror) {
@@ -168,70 +163,59 @@ int debug (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
/* Find %m in the input string and substitute an error message string. */
-static void do_percentm (obuf, ibuf)
+static void do_percentm (obuf, size, ibuf)
char *obuf;
+ size_t size;
char *ibuf;
{
+ char ch;
char *s = ibuf;
- char *p = obuf;
- int infmt = 0;
- const char *m;
-
- while (*s)
- {
- if (infmt)
- {
- if (*s == 'm')
- {
-#ifndef __CYGWIN32__
- m = strerror (errno);
-#else
- m = pWSAError ();
-#endif
- if (!m)
- m = "<unknown error>";
- strcpy (p - 1, m);
- p += strlen (p);
- ++s;
+ 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--;
}
- else
- *p++ = *s++;
- infmt = 0;
- }
- else
- {
- if (*s == '%')
- infmt = 1;
- *p++ = *s++;
}
}
- *p = 0;
+ *t = '\0';
}
-int parse_warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
+int parse_warn (char * fmt, ...)
KandR (char *fmt;)
va_dcl
{
va_list list;
static char spaces [] = " ";
- do_percentm (mbuf, fmt);
-#ifndef NO_SNPRINTF
+ do_percentm (mbuf, sizeof(mbuf), fmt);
snprintf (fbuf, sizeof fbuf, "%s line %d: %s",
tlname, lexline, mbuf);
-#else
- sprintf (fbuf, "%s line %d: %s",
- tlname, lexline, mbuf);
-#endif
-
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);
+ syslog (log_priority | LOG_ERR, mbuf);
+ syslog (log_priority | LOG_ERR, token_line);
if (lexline < 81)
syslog (log_priority | LOG_ERR,
"%s^", &spaces [sizeof spaces - lexchar]);
@@ -250,156 +234,3 @@ int parse_warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
return 0;
}
-
-void
-write_pidfile(file, pid)
- char *file;
- pid_t pid;
-{
- FILE *fp;
-
- (void)unlink(file);
-
- if ((fp = fopen(file , "w")) != NULL) {
- fprintf(fp, "%d\n", pid);
- (void)fclose(fp);
- }
-}
-
-#ifdef NO_STRERROR
-char *strerror (err)
- int err;
-{
- extern char *sys_errlist [];
- extern int sys_nerr;
- static char errbuf [128];
-
- if (err < 0 || err >= sys_nerr) {
- sprintf (errbuf, "Error %d", err);
- return errbuf;
- }
- return sys_errlist [err];
-}
-#endif /* NO_STRERROR */
-
-#ifdef _WIN32
-char *pWSAError ()
-{
- int err = WSAGetLastError ();
-
- switch (err)
- {
- case WSAEACCES:
- return "Permission denied";
- case WSAEADDRINUSE:
- return "Address already in use";
- case WSAEADDRNOTAVAIL:
- return "Cannot assign requested address";
- case WSAEAFNOSUPPORT:
- return "Address family not supported by protocol family";
- case WSAEALREADY:
- return "Operation already in progress";
- case WSAECONNABORTED:
- return "Software caused connection abort";
- case WSAECONNREFUSED:
- return "Connection refused";
- case WSAECONNRESET:
- return "Connection reset by peer";
- case WSAEDESTADDRREQ:
- return "Destination address required";
- case WSAEFAULT:
- return "Bad address";
- case WSAEHOSTDOWN:
- return "Host is down";
- case WSAEHOSTUNREACH:
- return "No route to host";
- case WSAEINPROGRESS:
- return "Operation now in progress";
- case WSAEINTR:
- return "Interrupted function call";
- case WSAEINVAL:
- return "Invalid argument";
- case WSAEISCONN:
- return "Socket is already connected";
- case WSAEMFILE:
- return "Too many open files";
- case WSAEMSGSIZE:
- return "Message too long";
- case WSAENETDOWN:
- return "Network is down";
- case WSAENETRESET:
- return "Network dropped connection on reset";
- case WSAENETUNREACH:
- return "Network is unreachable";
- case WSAENOBUFS:
- return "No buffer space available";
- case WSAENOPROTOOPT:
- return "Bad protocol option";
- case WSAENOTCONN:
- return "Socket is not connected";
- case WSAENOTSOCK:
- return "Socket operation on non-socket";
- case WSAEOPNOTSUPP:
- return "Operation not supported";
- case WSAEPFNOSUPPORT:
- return "Protocol family not supported";
- case WSAEPROCLIM:
- return "Too many processes";
- case WSAEPROTONOSUPPORT:
- return "Protocol not supported";
- case WSAEPROTOTYPE:
- return "Protocol wrong type for socket";
- case WSAESHUTDOWN:
- return "Cannot send after socket shutdown";
- case WSAESOCKTNOSUPPORT:
- return "Socket type not supported";
- case WSAETIMEDOUT:
- return "Connection timed out";
- case WSAEWOULDBLOCK:
- return "Resource temporarily unavailable";
- case WSAHOST_NOT_FOUND:
- return "Host not found";
-#if 0
- case WSA_INVALID_HANDLE:
- return "Specified event object handle is invalid";
- case WSA_INVALID_PARAMETER:
- return "One or more parameters are invalid";
- case WSAINVALIDPROCTABLE:
- return "Invalid procedure table from service provider";
- case WSAINVALIDPROVIDER:
- return "Invalid service provider version number";
- case WSA_IO_PENDING:
- return "Overlapped operations will complete later";
- case WSA_IO_INCOMPLETE:
- return "Overlapped I/O event object not in signaled state";
- case WSA_NOT_ENOUGH_MEMORY:
- return "Insufficient memory available";
-#endif
- case WSANOTINITIALISED:
- return "Successful WSAStartup not yet performer";
- case WSANO_DATA:
- return "Valid name, no data record of requested type";
- case WSANO_RECOVERY:
- return "This is a non-recoverable error";
-#if 0
- case WSAPROVIDERFAILEDINIT:
- return "Unable to initialize a service provider";
- case WSASYSCALLFAILURE:
- return "System call failure";
-#endif
- case WSASYSNOTREADY:
- return "Network subsystem is unavailable";
- case WSATRY_AGAIN:
- return "Non-authoritative host not found";
- case WSAVERNOTSUPPORTED:
- return "WINSOCK.DLL version out of range";
- case WSAEDISCON:
- return "Graceful shutdown in progress";
-#if 0
- case WSA_OPERATION_ABORTED:
- return "Overlapped operation aborted";
-#endif
- }
- return "Unknown WinSock error";
-}
-#endif /* _WIN32 */
diff --git a/usr.sbin/dhcp/common/ethernet.c b/usr.sbin/dhcp/common/ethernet.c
new file mode 100644
index 00000000000..1adface63a8
--- /dev/null
+++ b/usr.sbin/dhcp/common/ethernet.c
@@ -0,0 +1,92 @@
+/* packet.c
+
+ Packet assembly code, originally contributed by Archie Cobbs. */
+
+/*
+ * 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"
+
+#include <netinet/if_ether.h>
+#define ETHER_HEADER_SIZE (ETHER_ADDR_LEN * 2 + sizeof (u_int16_t))
+
+/* Assemble an hardware header... */
+/* XXX currently only supports ethernet; doesn't check for other types. */
+
+void assemble_ethernet_header (interface, buf, bufix, to)
+ struct interface_info *interface;
+ unsigned char *buf;
+ int *bufix;
+ struct hardware *to;
+{
+ struct ether_header eh;
+
+ if (to && 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;
+}
+
+/* Decode a hardware header... */
+
+ssize_t decode_ethernet_header (interface, buf, bufix, from)
+ struct interface_info *interface;
+ 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;
+}
diff --git a/usr.sbin/dhcp/common/hash.c b/usr.sbin/dhcp/common/hash.c
index 23892c7ce14..b4bba2186c9 100644
--- a/usr.sbin/dhcp/common/hash.c
+++ b/usr.sbin/dhcp/common/hash.c
@@ -3,7 +3,7 @@
Routines for manipulating hash tables... */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,14 +40,9 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: hash.c,v 1.1 1998/08/18 03:43:26 deraadt Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
-static INLINE int do_hash PROTO ((char *, int, int));
+static int do_hash PROTO ((unsigned char *, int, int));
struct hash_table *new_hash ()
{
@@ -59,31 +54,20 @@ struct hash_table *new_hash ()
return rv;
}
-static INLINE int do_hash (name, len, size)
- char *name;
+static int do_hash (name, len, size)
+ unsigned char *name;
int len;
int size;
{
register int accum = 0;
- register unsigned char *s = (unsigned char *)name;
+ register unsigned char *s = name;
int i = len;
- if (i) {
- while (i--) {
- /* Add the character in... */
- accum += *s++;
- /* Add carry back in... */
- while (accum > 255) {
- accum = (accum & 255) + (accum >> 8);
- }
- }
- } else {
- while (*s) {
- /* Add the character in... */
- accum += *s++;
- /* Add carry back in... */
- while (accum > 255) {
- accum = (accum & 255) + (accum >> 8);
- }
+ while (i--) {
+ /* Add the character in... */
+ accum += *s++;
+ /* Add carry back in... */
+ while (accum > 255) {
+ accum = (accum & 255) + (accum >> 8);
}
}
return accum % size;
@@ -92,7 +76,7 @@ static INLINE int do_hash (name, len, size)
void add_hash (table, name, len, pointer)
struct hash_table *table;
int len;
- char *name;
+ unsigned char *name;
unsigned char *pointer;
{
int hashno;
@@ -100,6 +84,8 @@ void add_hash (table, name, len, pointer)
if (!table)
return;
+ if (!len)
+ len = strlen ((char *)name);
hashno = do_hash (name, len, table -> hash_count);
bp = new_hash_bucket ("add_hash");
@@ -118,20 +104,23 @@ void add_hash (table, name, len, pointer)
void delete_hash_entry (table, name, len)
struct hash_table *table;
int len;
- char *name;
+ unsigned char *name;
{
int hashno;
struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
if (!table)
return;
+ if (!len)
+ len = strlen ((char *)name);
hashno = do_hash (name, len, table -> hash_count);
/* Go through the list looking for an entry that matches;
if we find it, delete it. */
for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
- if ((!bp -> len && !strcmp (bp -> name, name)) ||
+ if ((!bp -> len &&
+ !strcmp ((char *)bp -> name, (char *)name)) ||
(bp -> len == len &&
!memcmp (bp -> name, name, len))) {
if (pbp) {
@@ -148,7 +137,7 @@ void delete_hash_entry (table, name, len)
unsigned char *hash_lookup (table, name, len)
struct hash_table *table;
- char *name;
+ unsigned char *name;
int len;
{
int hashno;
@@ -156,19 +145,15 @@ unsigned char *hash_lookup (table, name, len)
if (!table)
return (unsigned char *)0;
+
+ if (!len)
+ len = strlen ((char *)name);
+
hashno = do_hash (name, len, table -> hash_count);
- if (len) {
- for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
- if (len == bp -> len
- && !memcmp (bp -> name, name, len))
- return bp -> value;
- }
- } else {
- for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
- if (!strcmp (bp -> name, name))
- return bp -> value;
+ for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
+ if (len == bp -> len && !memcmp (bp -> name, name, len))
+ return bp -> value;
}
return (unsigned char *)0;
}
-
diff --git a/usr.sbin/dhcp/common/icmp.c b/usr.sbin/dhcp/common/icmp.c
index d32553a02a3..d64aef0ab44 100644
--- a/usr.sbin/dhcp/common/icmp.c
+++ b/usr.sbin/dhcp/common/icmp.c
@@ -1,10 +1,10 @@
-/* dhcp.c
+/* icmp.c
ICMP Protocol engine - for sending out pings and receiving
responses. */
/*
- * Copyright (c) 1997 The Internet Software Consortium.
+ * Copyright (c) 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,14 +41,10 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: icmp.c,v 1.2 2001/01/03 16:04:38 ericj Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
-#include "netinet/ip.h"
-#include "netinet/ip_icmp.h"
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
static int icmp_protocol_initialized;
static int icmp_protocol_fd;
@@ -84,7 +80,8 @@ void icmp_startup (routep, handler)
(char *)&state, sizeof state) < 0)
error ("Unable to disable SO_DONTROUTE on ICMP socket: %m");
- add_protocol ("icmp", icmp_protocol_fd, icmp_echoreply, handler);
+ add_protocol ("icmp", icmp_protocol_fd, icmp_echoreply,
+ (void *)handler);
}
int icmp_echorequest (addr)
@@ -97,9 +94,7 @@ int icmp_echorequest (addr)
if (!icmp_protocol_initialized)
error ("attempt to use ICMP protocol before initialization.");
-#ifdef HAVE_SA_LEN
to.sin_len = sizeof to;
-#endif
to.sin_family = AF_INET;
to.sin_port = 0; /* unused. */
memcpy (&to.sin_addr, addr -> iabuf, sizeof to.sin_addr); /* XXX */
@@ -134,14 +129,14 @@ void icmp_echoreply (protocol)
{
struct icmp *icfrom;
struct sockaddr_in from;
- unsigned char icbuf [1500];
+ u_int8_t icbuf [1500];
int status;
int len;
struct iaddr ia;
void (*handler) PROTO ((struct iaddr, u_int8_t *, int));
len = sizeof from;
- status = recvfrom (protocol -> fd, icbuf, sizeof icbuf, 0,
+ status = recvfrom (protocol -> fd, (char *)icbuf, sizeof icbuf, 0,
(struct sockaddr *)&from, &len);
if (status < 0) {
warn ("icmp_echoreply: %m");
@@ -163,7 +158,9 @@ void icmp_echoreply (protocol)
/* If we were given a second-stage handler, call it. */
if (protocol -> local) {
- handler = protocol -> local;
+ handler = ((void (*) PROTO ((struct iaddr,
+ u_int8_t *, int)))
+ protocol -> local);
memcpy (ia.iabuf, &from.sin_addr, sizeof from.sin_addr);
ia.len = sizeof from.sin_addr;
diff --git a/usr.sbin/dhcp/common/inet.c b/usr.sbin/dhcp/common/inet.c
index 9f43950c3f6..16097b08185 100644
--- a/usr.sbin/dhcp/common/inet.c
+++ b/usr.sbin/dhcp/common/inet.c
@@ -64,8 +64,9 @@ struct iaddr subnet_number (addr, mask)
}
/* Combine a network number and a integer to produce an internet address.
- This won't work for subnets with more than 32 bits of host address, but
- maybe this isn't a problem. */
+ * This won't work for subnets with more than 32 bits of host address, but
+ * maybe this isn't a problem.
+ */
struct iaddr ip_addr (subnet, mask, host_address)
struct iaddr subnet;
@@ -163,16 +164,21 @@ int addr_eq (addr1, addr2)
char *piaddr (addr)
struct iaddr addr;
{
- static char pbuf [4 * 16];
- char *s = pbuf;
- int i;
+ static char pbuf [32];
+ char *s;
+ struct in_addr a;
+
+ memcpy(&a, &(addr.iabuf), sizeof(struct in_addr));
if (addr.len == 0) {
- strcpy (s, "<null address>");
- }
- for (i = 0; i < addr.len; i++) {
- sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
- s += strlen (s);
+ strlcpy (pbuf, "<null address>", sizeof(pbuf));
}
- return pbuf;
+ else {
+ s = inet_ntoa(a);
+ if (s != NULL)
+ strlcpy(pbuf, s, sizeof(pbuf));
+ else
+ strlcpy (pbuf, "<invalid address>", sizeof(pbuf));
+ }
+ return(pbuf);
}
diff --git a/usr.sbin/dhcp/common/inet_addr.c b/usr.sbin/dhcp/common/inet_addr.c
deleted file mode 100644
index 312e63f7f1e..00000000000
--- a/usr.sbin/dhcp/common/inet_addr.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/* $NetBSD: inet_addr.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $ */
-
-/*
- * Copyright (c) 1983, 1990, 1993
- * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
-#else
-static char rcsid[] = "$NetBSD: inet_addr.c,v 1.1.1.1 1997/03/29 21:52:17 mellon Exp $";
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef lint
-static char copyright[] =
-"$Id: inet_addr.c,v 1.1 1998/08/18 03:43:26 deraadt Exp $ Copyright (c) 1983, 1990, 1993 The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#ifdef NEED_INET_ATON
-/*
- * Check whether "cp" is a valid ascii representation
- * of an Internet address and convert to a binary address.
- * Returns 1 if the address is valid, 0 if not.
- * This replaces inet_addr, the return value from which
- * cannot distinguish between failure and a local broadcast address.
- */
-int
-inet_aton(cp, addr)
- char *cp;
- struct in_addr *addr;
-{
- register u_long val;
- register int base, n;
- register char c;
- u_int parts[4];
- register u_int *pp = parts;
-
- for (;;) {
- /*
- * Collect number up to ``.''.
- * Values are specified as for C:
- * 0x=hex, 0=octal, other=decimal.
- */
- val = 0; base = 10;
- if (*cp == '0') {
- if (*++cp == 'x' || *cp == 'X')
- base = 16, cp++;
- else
- base = 8;
- }
- while ((c = *cp) != '\0') {
- if (isascii(c) && isdigit(c)) {
- val = (val * base) + (c - '0');
- cp++;
- continue;
- }
- if (base == 16 && isascii(c) && isxdigit(c)) {
- val = (val << 4) +
- (c + 10 - (islower(c) ? 'a' : 'A'));
- cp++;
- continue;
- }
- break;
- }
- if (*cp == '.') {
- /*
- * Internet format:
- * a.b.c.d
- * a.b.c (with c treated as 16-bits)
- * a.b (with b treated as 24 bits)
- */
- if (pp >= parts + 3 || val > 0xff)
- return (0);
- *pp++ = val, cp++;
- } else
- break;
- }
- /*
- * Check for trailing characters.
- */
- if (*cp && (!isascii(*cp) || !isspace(*cp)))
- return (0);
- /*
- * Concoct the address according to
- * the number of parts specified.
- */
- n = pp - parts + 1;
- switch (n) {
-
- case 0:
- return (0); /* initial nondigit */
-
- case 1: /* a -- 32 bits */
- break;
-
- case 2: /* a.b -- 8.24 bits */
- if (val > 0xffffff)
- return (0);
- val |= parts[0] << 24;
- break;
-
- case 3: /* a.b.c -- 8.8.16 bits */
- if (val > 0xffff)
- return (0);
- val |= (parts[0] << 24) | (parts[1] << 16);
- break;
-
- case 4: /* a.b.c.d -- 8.8.8.8 bits */
- if (val > 0xff)
- return (0);
- val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
- break;
- }
- if (addr)
- addr->s_addr = htonl(val);
- return (1);
-}
-#endif
diff --git a/usr.sbin/dhcp/common/memory.c b/usr.sbin/dhcp/common/memory.c
index b8674016f0a..d383320bf8a 100644
--- a/usr.sbin/dhcp/common/memory.c
+++ b/usr.sbin/dhcp/common/memory.c
@@ -3,7 +3,7 @@
Memory-resident database... */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,11 +40,6 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: memory.c,v 1.3 2000/07/21 00:33:53 beck Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
static struct subnet *subnets;
@@ -206,7 +201,7 @@ void new_address_range (low, high, subnet, dynamic)
/* All subnets should have attached shared network structures. */
if (!share) {
- strcpy (netbuf, piaddr (subnet -> net));
+ strlcpy (netbuf, piaddr (subnet -> net), sizeof(netbuf));
error ("No shared network for network %s (%s)",
netbuf, piaddr (subnet -> netmask));
}
@@ -222,18 +217,18 @@ void new_address_range (low, high, subnet, dynamic)
/* Make sure that high and low addresses are in same subnet. */
net = subnet_number (low, subnet -> netmask);
if (!addr_eq (net, subnet_number (high, subnet -> netmask))) {
- strcpy (lowbuf, piaddr (low));
- strcpy (highbuf, piaddr (high));
- strcpy (netbuf, piaddr (subnet -> netmask));
+ strlcpy (lowbuf, piaddr (low), sizeof(lowbuf));
+ strlcpy (highbuf, piaddr (high), sizeof(highbuf));
+ strlcpy (netbuf, piaddr (subnet -> netmask), sizeof(netbuf));
error ("Address range %s to %s, netmask %s spans %s!",
lowbuf, highbuf, netbuf, "multiple subnets");
}
/* Make sure that the addresses are on the correct subnet. */
if (!addr_eq (net, subnet -> net)) {
- strcpy (lowbuf, piaddr (low));
- strcpy (highbuf, piaddr (high));
- strcpy (netbuf, piaddr (subnet -> netmask));
+ strlcpy (lowbuf, piaddr (low), sizeof(lowbuf));
+ strlcpy (highbuf, piaddr (high), sizeof(highbuf));
+ strlcpy (netbuf, piaddr (subnet -> netmask), sizeof(netbuf));
error ("Address range %s to %s not on net %s/%s!",
lowbuf, highbuf, piaddr (subnet -> net), netbuf);
}
@@ -251,8 +246,8 @@ void new_address_range (low, high, subnet, dynamic)
/* Get a lease structure for each address in the range. */
address_range = new_leases (max - min + 1, "new_address_range");
if (!address_range) {
- strcpy (lowbuf, piaddr (low));
- strcpy (highbuf, piaddr (high));
+ strlcpy (lowbuf, piaddr (low), sizeof(lowbuf));
+ strlcpy (highbuf, piaddr (high), sizeof(highbuf));
error ("No memory for address range %s-%s.", lowbuf, highbuf);
}
memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
@@ -280,13 +275,14 @@ void new_address_range (low, high, subnet, dynamic)
if (!h)
warn ("No hostname for %s", inet_ntoa (ia));
else {
+ int len = strlen(h->h_name) + 1;
address_range [i].hostname =
- malloc (strlen (h -> h_name) + 1);
+ malloc (len);
if (!address_range [i].hostname)
error ("no memory for hostname %s.",
h -> h_name);
- strcpy (address_range [i].hostname,
- h -> h_name);
+ strlcpy (address_range [i].hostname,
+ h -> h_name, len);
}
}
@@ -357,36 +353,59 @@ struct subnet *find_grouped_subnet (share, addr)
return (struct subnet *)0;
}
+int subnet_inner_than (subnet, scan, warnp)
+ struct subnet *subnet, *scan;
+ int warnp;
+{
+ if (addr_eq (subnet_number (subnet -> net, scan -> netmask),
+ scan -> net) ||
+ addr_eq (subnet_number (scan -> net, subnet -> netmask),
+ subnet -> net)) {
+ char n1buf [16];
+ int i, j;
+ for (i = 0; i < 32; i++)
+ if (subnet -> netmask.iabuf [3 - (i >> 3)]
+ & (1 << (i & 7)))
+ break;
+ for (j = 0; j < 32; j++)
+ if (scan -> netmask.iabuf [3 - (j >> 3)] &
+ (1 << (j & 7)))
+ break;
+ strlcpy (n1buf, piaddr (subnet -> net), sizeof(n1buf));
+ if (warnp)
+ warn ("%ssubnet %s/%d conflicts with subnet %s/%d",
+ "Warning: ", n1buf, 32 - i,
+ piaddr (scan -> net), 32 - j);
+ if (i < j)
+ return 1;
+ }
+ return 0;
+}
+
/* Enter a new subnet into the subnet list. */
void enter_subnet (subnet)
struct subnet *subnet;
{
- struct subnet *scan;
+ struct subnet *scan, *prev = (struct subnet *)0;
/* Check for duplicates... */
for (scan = subnets; scan; scan = scan -> next_subnet) {
- if (addr_eq (subnet_number (subnet -> net, scan -> netmask),
- scan -> net) ||
- addr_eq (subnet_number (scan -> net, subnet -> netmask),
- subnet -> net)) {
- char n1buf [16];
- int i, j;
- for (i = 0; i < 32; i++)
- if (subnet -> netmask.iabuf [3 - (i >> 3)]
- & (1 << (i & 7)))
- break;
- for (j = 0; j < 32; j++)
- if (scan -> netmask.iabuf [3 - (j >> 3)]
- & (1 << (j & 7)))
- break;
- strcpy (n1buf, piaddr (subnet -> net));
- error ("subnet %s/%d conflicts with subnet %s/%d",
- n1buf, i, piaddr (scan -> net), j);
+ /* When we find a conflict, make sure that the
+ subnet with the narrowest subnet mask comes
+ first. */
+ if (subnet_inner_than (subnet, scan, 1)) {
+ if (prev) {
+ prev -> next_subnet = subnet;
+ } else
+ subnets = subnet;
+ subnet -> next_subnet = scan;
+ return;
}
+ prev = scan;
}
- /* XXX Sort the nets into a balanced tree to make searching quicker. */
+ /* XXX use the BSD radix tree code instead of a linked list. */
subnet -> next_subnet = subnets;
subnets = subnet;
}
@@ -421,9 +440,9 @@ void enter_lease (lease)
piaddr (lease -> ip_addr));
}
*comp = *lease;
- lease -> next = dangling_leases;
- lease -> prev = (struct lease *)0;
- dangling_leases = lease;
+ comp -> next = dangling_leases;
+ comp -> prev = (struct lease *)0;
+ dangling_leases = comp;
} else {
/* Record the hostname information in the lease. */
comp -> hostname = lease -> hostname;
@@ -504,7 +523,6 @@ int supersede_lease (comp, lease, commit)
/* Copy the data files, but not the linkages. */
comp -> starts = lease -> starts;
- comp -> timestamp = lease -> timestamp;
if (lease -> uid) {
if (lease -> uid_len < sizeof (lease -> uid_buf)) {
memcpy (comp -> uid_buf,
@@ -626,12 +644,15 @@ void release_lease (lease)
struct lease lt;
lt = *lease;
- lt.ends = cur_time;
- supersede_lease (lease, &lt, 1);
- note ("Released lease for IP address %s",
- piaddr (lease -> ip_addr));
+ if (lt.ends > cur_time) {
+ lt.ends = cur_time;
+ supersede_lease (lease, &lt, 1);
+ note ("Released lease for IP address %s",
+ piaddr (lease -> ip_addr));
+ }
}
+
/* Abandon the specified lease for the specified time. sets it's
particulars to zero, the end time apropriately and re-hash it as
appropriate. abandons permanently if abtime is 0 */
@@ -838,21 +859,23 @@ struct class *add_class (type, name)
return (struct class *)0;
memset (class, 0, sizeof *class);
- strcpy (tname, name);
+ strlcpy (tname, name, strlen(name) + 1);
class -> name = tname;
if (type)
add_hash (user_class_hash,
- tname, strlen (tname), (unsigned char *)class);
+ (unsigned char *)tname, strlen (tname),
+ (unsigned char *)class);
else
add_hash (vendor_class_hash,
- tname, strlen (tname), (unsigned char *)class);
+ (unsigned char *)tname, strlen (tname),
+ (unsigned char *)class);
return class;
}
struct class *find_class (type, name, len)
int type;
- char *name;
+ unsigned char *name;
int len;
{
struct class *class =
@@ -899,16 +922,21 @@ void dump_subnets ()
struct shared_network *s;
struct subnet *n;
+ note ("Subnets:");
+ for (n = subnets; n; n = n -> next_subnet) {
+ debug (" Subnet %s", piaddr (n -> net));
+ debug (" netmask %s",
+ piaddr (n -> netmask));
+ }
+ note ("Shared networks:");
for (s = shared_networks; s; s = s -> next) {
- for (n = subnets; n; n = n -> next_sibling) {
- debug ("Subnet %s", piaddr (n -> net));
- debug (" netmask %s",
- piaddr (n -> netmask));
- }
+ note (" %s", s -> name);
for (l = s -> leases; l; l = l -> next) {
print_lease (l);
}
- debug ("Last Lease:");
- print_lease (s -> last_lease);
+ if (s -> last_lease) {
+ debug (" Last Lease:");
+ print_lease (s -> last_lease);
+ }
}
}
diff --git a/usr.sbin/dhcp/common/nit.c b/usr.sbin/dhcp/common/nit.c
deleted file mode 100644
index 296c17a3a1c..00000000000
--- a/usr.sbin/dhcp/common/nit.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* nit.c
-
- Network Interface Tap (NIT) network interface code, by Ted Lemon
- with one crucial tidbit of help from Stu Grossmen. */
-
-/*
- * 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''. */
-
-#ifndef lint
-static char copyright[] =
-"$Id: nit.c,v 1.1 1998/08/18 03:43:26 deraadt Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#if defined (USE_NIT_SEND) || defined (USE_NIT_RECEIVE)
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include <sys/time.h>
-#include <net/nit.h>
-#include <net/nit_if.h>
-#include <net/nit_pf.h>
-#include <net/nit_buf.h>
-#include <sys/stropts.h>
-#include <net/packetfilt.h>
-
-#include <netinet/in_systm.h>
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-
-/* Reinitializes the specified interface after an address change. This
- is not required for packet-filter APIs. */
-
-#ifdef USE_NIT_SEND
-void if_reinitialize_send (info)
- struct interface_info *info;
-{
-}
-#endif
-
-#ifdef USE_NIT_RECEIVE
-void if_reinitialize_receive (info)
- struct interface_info *info;
-{
-}
-#endif
-
-/* 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_nit (info)
- struct interface_info *info;
-{
- int sock;
- char filename[50];
- struct ifreq ifr;
- struct strioctl sio;
-
- /* Open a NIT device */
- sock = open ("/dev/nit", O_RDWR);
- if (sock < 0)
- error ("Can't open NIT device for %s: %m", info -> name);
-
- /* Set the NIT device to point at this interface. */
- sio.ic_cmd = NIOCBIND;
- sio.ic_len = sizeof *(info -> ifp);
- sio.ic_dp = (char *)(info -> ifp);
- sio.ic_timout = INFTIM;
- if (ioctl (sock, I_STR, &sio) < 0)
- error ("Can't attach interface %s to nit device: %m",
- info -> name);
-
- /* Get the low-level address... */
- sio.ic_cmd = SIOCGIFADDR;
- sio.ic_len = sizeof ifr;
- sio.ic_dp = (char *)&ifr;
- sio.ic_timout = INFTIM;
- if (ioctl (sock, I_STR, &sio) < 0)
- error ("Can't get physical layer address for %s: %m",
- info -> name);
-
- /* XXX code below assumes ethernet interface! */
- info -> hw_address.hlen = 6;
- info -> hw_address.htype = ARPHRD_ETHER;
- memcpy (info -> hw_address.haddr, ifr.ifr_ifru.ifru_addr.sa_data, 6);
-
- if (ioctl (sock, I_PUSH, "pf") < 0)
- error ("Can't push packet filter onto NIT for %s: %m",
- info -> name);
-
- return sock;
-}
-#endif /* USE_NIT_SEND || USE_NIT_RECEIVE */
-
-#ifdef USE_NIT_SEND
-void if_register_send (info)
- struct interface_info *info;
-{
- /* If we're using the nit API for sending and receiving,
- we don't need to register this interface twice. */
-#ifndef USE_NIT_RECEIVE
- struct packetfilt pf;
- struct strioctl sio;
-
- info -> wfdesc = if_register_nit (info);
-
- pf.Pf_Priority = 0;
- pf.Pf_FilterLen = 1;
- pf.Pf_Filter [0] = ENF_PUSHZERO;
-
- /* Set up an NIT filter that rejects everything... */
- sio.ic_cmd = NIOCSETF;
- sio.ic_len = sizeof pf;
- sio.ic_dp = (char *)&pf;
- sio.ic_timout = INFTIM;
- if (ioctl (info -> wfdesc, I_STR, &sio) < 0)
- error ("Can't set NIT filter: %m");
-#else
- info -> wfdesc = info -> rfdesc;
-#endif
- if (!quiet_interface_discovery)
- note ("Sending on NIT/%s/%s",
- print_hw_addr (info -> hw_address.htype,
- info -> hw_address.hlen,
- info -> hw_address.haddr),
- (info -> shared_network ?
- info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_NIT_SEND */
-
-#ifdef USE_NIT_RECEIVE
-/* Packet filter program...
- XXX Changes to the filter program may require changes to the constant
- offsets used in if_register_send to patch the NIT program! XXX */
-
-void if_register_receive (info)
- struct interface_info *info;
-{
- int flag = 1;
- u_int32_t x;
- struct packetfilt pf;
- struct strioctl sio;
- u_int16_t addr [2];
- struct timeval t;
-
- /* Open a NIT device and hang it on this interface... */
- info -> rfdesc = if_register_nit (info);
-
- /* Set the snap length to 0, which means always take the whole
- packet. */
- x = 0;
- if (ioctl (info -> rfdesc, NIOCSSNAP, &x) < 0)
- error ("Can't set NIT snap length on %s: %m", info -> name);
-
- /* Set the stream to byte stream mode */
- if (ioctl (info -> rfdesc, I_SRDOPT, RMSGN) != 0)
- note ("I_SRDOPT failed on %s: %m", info -> name);
-
-#if 0
- /* Push on the chunker... */
- if (ioctl (info -> rfdesc, I_PUSH, "nbuf") < 0)
- error ("Can't push chunker onto NIT STREAM: %m");
-
- /* Set the timeout to zero. */
- t.tv_sec = 0;
- t.tv_usec = 0;
- if (ioctl (info -> rfdesc, NIOCSTIME, &t) < 0)
- error ("Can't set chunk timeout: %m");
-#endif
-
- /* Ask for no header... */
- x = 0;
- if (ioctl (info -> rfdesc, NIOCSFLAGS, &x) < 0)
- error ("Can't set NIT flags on %s: %m", info -> name);
-
- /* Set up the NIT filter program. */
- /* XXX Unlike the BPF filter program, this one won't work if the
- XXX IP packet is fragmented or if there are options on the IP
- XXX header. */
- pf.Pf_Priority = 0;
- pf.Pf_FilterLen = 0;
-
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 6;
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
- pf.Pf_Filter [pf.Pf_FilterLen++] = htons (ETHERTYPE_IP);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT;
- pf.Pf_Filter [pf.Pf_FilterLen++] = htons (IPPROTO_UDP);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 11;
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
- pf.Pf_Filter [pf.Pf_FilterLen++] = htons (0xFF);
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_CAND;
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 18;
- pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
- pf.Pf_Filter [pf.Pf_FilterLen++] = local_port;
-
- /* Install the filter... */
- sio.ic_cmd = NIOCSETF;
- sio.ic_len = sizeof pf;
- sio.ic_dp = (char *)&pf;
- sio.ic_timout = INFTIM;
- if (ioctl (info -> rfdesc, I_STR, &sio) < 0)
- error ("Can't set NIT filter on %s: %m", info -> name);
-
- if (!quiet_interface_discovery)
- note ("Listening on NIT/%s/%s",
- print_hw_addr (info -> hw_address.htype,
- info -> hw_address.hlen,
- info -> hw_address.haddr),
- (info -> shared_network ?
- info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_NIT_RECEIVE */
-
-#ifdef USE_NIT_SEND
-ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
- struct dhcp_packet *raw;
- size_t len;
- struct in_addr from;
- struct sockaddr_in *to;
- struct hardware *hto;
-{
- int bufp;
- unsigned char buf [1536 + sizeof (struct sockaddr)];
- struct sockaddr *junk;
- struct strbuf ctl, data;
- int hw_end;
- struct sockaddr_in foo;
-
- /* Start with the sockaddr struct... */
- junk = (struct sockaddr *)&buf [0];
- bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
-
- /* Assemble the headers... */
- assemble_hw_header (interface, buf, &bufp, hto);
- hw_end = bufp;
- assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
- to -> sin_addr.s_addr, to -> sin_port,
- raw, len);
-
- /* Copy the data into the buffer (yuk). */
- memcpy (buf + bufp, raw, len);
-
- /* Set up the sockaddr structure... */
-#if USE_SIN_LEN
- junk -> sa_len = hw_end - 2; /* XXX */
-#endif
- junk -> sa_family = AF_UNSPEC;
-
-#if 0 /* Already done. */
- memcpy (junk.sa_data, buf, hw_len);
-#endif
-
- /* Set up the msg_buf structure... */
- ctl.buf = (char *)&buf [0];
- ctl.maxlen = ctl.len = hw_end;
- data.buf = (char *)&buf [hw_end];
- data.maxlen = data.len = bufp + len - hw_end;
-
- return putmsg (interface -> wfdesc, &ctl, &data, 0);
-}
-#endif /* USE_NIT_SEND */
-
-#ifdef USE_NIT_RECEIVE
-ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
- size_t len;
- struct sockaddr_in *from;
- struct hardware *hfrom;
-{
- int nread;
- int length = 0;
- int offset = 0;
- unsigned char ibuf [1536];
- int bufix = 0;
-
- length = read (interface -> rfdesc, ibuf, sizeof ibuf);
- if (length <= 0)
- return length;
-
- /* Decode the physical header... */
- offset = decode_hw_header (interface, ibuf, bufix, hfrom);
-
- /* If a physical layer checksum failed (dunno of any
- physical layer that supports this, but WTH), skip this
- packet. */
- if (offset < 0) {
- return 0;
- }
-
- bufix += offset;
- length -= offset;
-
- /* Decode the IP and UDP headers... */
- offset = decode_udp_ip_header (interface, ibuf, bufix,
- from, (unsigned char *)0, length);
-
- /* If the IP or UDP checksum was bad, skip the packet... */
- if (offset < 0)
- return 0;
-
- bufix += offset;
- length -= offset;
-
- /* Copy out the data in the packet... */
- memcpy (buf, &ibuf [bufix], length);
- return length;
-}
-#endif
diff --git a/usr.sbin/dhcp/common/options.c b/usr.sbin/dhcp/common/options.c
index 61064a97673..b88e6fcc0a7 100644
--- a/usr.sbin/dhcp/common/options.c
+++ b/usr.sbin/dhcp/common/options.c
@@ -3,7 +3,7 @@
DHCP options parsing and reassembly. */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,13 +40,12 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: options.c,v 1.2 2000/11/10 15:33:13 provos Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#define DHCP_OPTION_DATA
#include "dhcpd.h"
+#include <ctype.h>
+
+int bad_options = 0;
+int bad_options_max = 5;
/* Parse all available options out of the specified packet. */
@@ -72,10 +71,12 @@ void parse_options (packet)
&& 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);
}
@@ -97,27 +98,51 @@ void parse_option_buffer (packet, buffer, length)
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, the options are bad. */
+ /* If the length is outrageous, silently skip the
+ * rest, and mark the packet bad. Unfortuntely
+ * 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) {
- warn ("Option %s length %d overflows input buffer.",
- dhcp_options [code].name,
- len);
- packet -> options_valid = 0;
+ bogus:
+ bad_options++;
+ warn ("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;
+ warn ("Many bogus options seen in offers.");
+ warn ("Taking this offer in spite of bogus");
+ warn ("options - hope for the best!");
+ } else {
+ warn ("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 = (unsigned char *)malloc (len + 1)))
+ if (!(t = ((unsigned char *)
+ dmalloc (len + 1, "parse_option_buffer"))))
error ("Can't allocate storage for option %s.",
dhcp_options [code].name);
/* Copy and NUL-terminate the option (in case it's an
@@ -130,10 +155,9 @@ void parse_option_buffer (packet, buffer, length)
/* If it's a repeat, concatenate it to whatever
we last saw. This is really only required
for clients, but what the heck... */
- t = (unsigned char *)
- malloc (len
- + packet -> options [code].len
- + 1);
+ t = ((unsigned char *)
+ dmalloc (len + packet -> options [code].len + 1,
+ "parse_option_buffer"));
if (!t)
error ("Can't expand storage for option %s.",
dhcp_options [code].name);
@@ -143,7 +167,8 @@ void parse_option_buffer (packet, buffer, length)
&s [2], len);
packet -> options [code].len += len;
t [packet -> options [code].len] = 0;
- free (packet -> options [code].data);
+ dfree (packet -> options [code].data,
+ "parse_option_buffer");
packet -> options [code].data = t;
}
s += len + 2;
@@ -152,16 +177,20 @@ void parse_option_buffer (packet, buffer, length)
}
/* 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
+ three seperate buffers if needed. This allows us to cons up a set
of vendor options using the same routine. */
-int cons_options (inpacket, outpacket, options, overload, terminate, bootpp)
+int cons_options (inpacket, outpacket, mms,
+ options, overload, terminate, bootpp, prl, prl_len)
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];
int priority_len;
@@ -176,21 +205,29 @@ int cons_options (inpacket, outpacket, options, overload, terminate, bootpp)
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 (inpacket && inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data) {
- main_buffer_size =
- (getUShort (inpacket -> options
- [DHO_DHCP_MAX_MESSAGE_SIZE].data)
- - DHCP_FIXED_LEN);
- /* Enforce a minimum packet size... */
- if (main_buffer_size < (576 - DHCP_FIXED_LEN))
- main_buffer_size = 576 - DHCP_FIXED_LEN;
- if (main_buffer_size > sizeof buffer)
- main_buffer_size = sizeof buffer;
- } else if (bootpp)
+ 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 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)
+ 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;
@@ -210,9 +247,17 @@ int cons_options (inpacket, outpacket, options, overload, terminate, bootpp)
prlen = (sizeof priority_list) - priority_len;
memcpy (&priority_list [priority_len],
- inpacket -> options
- [DHO_DHCP_PARAMETER_REQUEST_LIST].data, prlen);
+ (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,
@@ -416,12 +461,14 @@ char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
int numhunk = -1;
int numelem = 0;
char fmtbuf [32];
- int i, j;
+ int i, j, k;
char *op = optbuf;
+ int 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\n", code);
@@ -448,11 +495,21 @@ char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
numhunk = 0;
break;
case 'X':
- fmtbuf [i] = '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;
- hunksize++;
- numhunk = 0;
- comma = ':';
break;
case 't':
fmtbuf [i] = 't';
@@ -512,79 +569,135 @@ char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
/* 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)
+ if (emit_quotes) {
*op++ = '"';
- strcpy (op, dp);
- op += strlen (dp);
- if (emit_quotes)
+ opleft--;
+ }
+ for (; dp < data + len; dp++) {
+ if (!isascii (*dp) ||
+ !isprint (*dp)) {
+ 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));
- strcpy (op, inet_ntoa (foo));
+ foo.s_addr = htonl(getULong (dp));
+ opcount = strlcpy(op, inet_ntoa (foo),
+ opleft);
+ opleft -= opcount;
dp += 4;
break;
case 'l':
- sprintf (op, "%ld", (long)getLong (dp));
+ opcount = snprintf(op, opleft,"%ld",
+ (long)getLong (dp));
+ opleft -= opcount;
dp += 4;
break;
case 'L':
- sprintf (op, "%ld",
- (unsigned long)getULong (dp));
+ opcount = snprintf(op, opleft, "%ld",
+ (unsigned long)getULong (dp));
+ opleft -= opcount;
dp += 4;
break;
case 's':
- sprintf (op, "%d", getShort (dp));
+ opcount = snprintf(op, opleft, "%d",
+ getShort (dp));
+ opleft -= opcount;
dp += 2;
break;
case 'S':
- sprintf (op, "%d", getUShort (dp));
+ opcount = snprintf(op, opleft, "%d",
+ getUShort (dp));
+ opleft -= opcount;
dp += 2;
break;
case 'b':
- sprintf (op, "%d", *(char *)dp++);
+ opcount = snprintf(op, opleft, "%d",
+ *(char *)dp++);
+ opleft -= opcount;
break;
case 'B':
- sprintf (op, "%d", *dp++);
+ opcount = snprintf(op, opleft, "%d", *dp++);
+ opleft -= opcount;
break;
case 'x':
- sprintf (op, "%x", *dp++);
+ opcount = snprintf(op, opleft, "%x", *dp++);
+ opleft -= opcount;
break;
- case 'f':
- strcpy (op, *dp++ ? "true" : "false");
+ case 'f':
+ opcount = strlcpy(op,
+ *dp++ ? "true" : "false", opleft);
+ opleft -= opcount;
break;
default:
warn ("Unexpected format code %c", fmtbuf [j]);
}
op += strlen (op);
- if (j + 1 < numelem && comma != ':')
+ opleft -= strlen(op);
+ if (opleft < 1) {
+ warn ("dhcp option too large");
+ return "<error>";
+ }
+ if (j + 1 < numelem && comma != ':') {
*op++ = ' ';
+ opleft--;
+ }
}
if (i + 1 < numhunk) {
*op++ = comma;
+ opleft--;
+ }
+ if (opleft < 1) {
+ warn ("dhcp option too large");
+ return "<error>";
}
}
return optbuf;
}
-void do_packet (interface, packbuf, len, from_port, from, hfrom)
+void do_packet (interface, packet, len, from_port, from, hfrom)
struct interface_info *interface;
- unsigned char *packbuf;
+ struct dhcp_packet *packet;
int len;
- unsigned short from_port;
+ unsigned int from_port;
struct iaddr from;
struct hardware *hfrom;
{
struct packet tp;
- struct dhcp_packet tdp;
+ int i;
+
+ if (packet -> hlen > sizeof packet -> chaddr) {
+ note ("Discarding packet with invalid hlen.");
+ return;
+ }
- memcpy (&tdp, packbuf, len);
memset (&tp, 0, sizeof tp);
- tp.raw = &tdp;
+ tp.raw = packet;
tp.packet_length = len;
tp.client_port = from_port;
tp.client_addr = from;
@@ -600,5 +713,11 @@ void do_packet (interface, packbuf, len, from_port, from, hfrom)
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)
+ dfree (tp.options [i].data, "do_packet");
+ }
}
diff --git a/usr.sbin/dhcp/common/packet.c b/usr.sbin/dhcp/common/packet.c
index 5b136c394ff..499f20cb1bf 100644
--- a/usr.sbin/dhcp/common/packet.c
+++ b/usr.sbin/dhcp/common/packet.c
@@ -3,7 +3,7 @@
Packet assembly code, originally contributed by Archie Cobbs. */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,18 +40,11 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: packet.c,v 1.3 2001/01/14 23:01:19 angelos Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
-#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
/* Compute the easy part of the checksum on a range of bytes. */
@@ -60,7 +53,7 @@ u_int32_t checksum (buf, nbytes, sum)
unsigned nbytes;
u_int32_t sum;
{
- unsigned i;
+ int i;
#ifdef DEBUG_CHECKSUM
debug ("checksum (%x %d %x)", buf, nbytes, sum);
@@ -92,7 +85,7 @@ u_int32_t checksum (buf, nbytes, sum)
return sum;
}
-/* Finish computing the checksum, and then put it into network byte order. */
+/* Finish computing the sum, and then put it into network byte order. */
u_int32_t wrapsum (sum)
u_int32_t sum;
@@ -103,7 +96,7 @@ u_int32_t wrapsum (sum)
sum = ~sum & 0xFFFF;
#ifdef DEBUG_CHECKSUM_VERBOSE
- log_debug ("sum = %x", sum);
+ debug ("sum = %x", sum);
#endif
#ifdef DEBUG_CHECKSUM
@@ -112,7 +105,6 @@ u_int32_t wrapsum (sum)
return htons(sum);
}
-#ifdef PACKET_ASSEMBLY
/* Assemble an hardware header... */
/* XXX currently only supports ethernet; doesn't check for other types. */
@@ -122,26 +114,13 @@ void assemble_hw_header (interface, buf, bufix, to)
int *bufix;
struct hardware *to;
{
- struct ether_header eh;
-
- if (to && 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));
+#if defined (HAVE_TR_SUPPORT)
+ if (interface -> hw_address.htype == HTYPE_IEEE802)
+ assemble_tr_header (interface, buf, bufix, to);
else
- memset (eh.ether_shost, 0x00, sizeof (eh.ether_shost));
-
-#ifdef BROKEN_FREEBSD_BPF /* Fixed in FreeBSD 2.2 */
- eh.ether_type = ETHERTYPE_IP;
-#else
- eh.ether_type = htons (ETHERTYPE_IP);
#endif
+ assemble_ethernet_header (interface, buf, bufix, to);
- memcpy (&buf [*bufix], &eh, sizeof eh);
- *bufix += sizeof eh;
}
/* UDP header and IP header assembled together for convenience. */
@@ -153,7 +132,7 @@ void assemble_udp_ip_header (interface, buf, bufix,
int *bufix;
u_int32_t from;
u_int32_t to;
- u_int16_t port;
+ unsigned int port;
unsigned char *data;
int len;
{
@@ -189,7 +168,6 @@ void assemble_udp_ip_header (interface, buf, bufix,
/* Compute UDP checksums, including the ``pseudo-header'', the UDP
header and the data. */
-#if 1
udp.uh_sum =
wrapsum (checksum ((unsigned char *)&udp, sizeof udp,
checksum (data, len,
@@ -199,17 +177,13 @@ void assemble_udp_ip_header (interface, buf, bufix,
IPPROTO_UDP +
(u_int32_t)
ntohs (udp.uh_ulen)))));
-#endif
/* Copy the udp header into the buffer... */
memcpy (&buf [*bufix], &udp, sizeof udp);
*bufix += sizeof udp;
}
-#endif /* PACKET_ASSEMBLY */
-#ifdef PACKET_DECODING
/* Decode a hardware header... */
-/* XXX currently only supports ethernet; doesn't check for other types. */
ssize_t decode_hw_header (interface, buf, bufix, from)
struct interface_info *interface;
@@ -217,55 +191,57 @@ ssize_t decode_hw_header (interface, buf, bufix, from)
int bufix;
struct hardware *from;
{
- struct ether_header eh;
-
- memcpy (&eh, buf + bufix, sizeof eh);
-
-#ifdef USERLAND_FILTER
- if (ntohs (eh.ether_type) != ETHERTYPE_IP)
- return -1;
+#if defined (HAVE_TR_SUPPORT)
+ if (interface -> hw_address.htype == HTYPE_IEEE802)
+ return decode_tr_header (interface, buf, bufix, from);
+ else
#endif
- memcpy (from -> haddr, eh.ether_shost, sizeof (eh.ether_shost));
- from -> htype = ARPHRD_ETHER;
- from -> hlen = sizeof eh.ether_shost;
-
- return sizeof eh;
+ return decode_ethernet_header (interface, buf, bufix, from);
}
/* UDP header and IP header decoded together for convenience. */
-ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len)
+ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, buflen)
struct interface_info *interface;
unsigned char *buf;
int bufix;
struct sockaddr_in *from;
unsigned char *data;
- int len;
+ 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);
-#ifdef USERLAND_FILTER
- /* Is it a UDP packet? */
- if (ip -> ip_p != IPPROTO_UDP)
- return -1;
-
- /* Is it to the port we're serving? */
- if (udp -> uh_dport != local_port)
- return -1;
-#endif /* USERLAND_FILTER */
-
/* Check the IP header checksum - it should be zero. */
+ ++ip_packets_seen;
if (wrapsum (checksum (buf + bufix, ip_len, 0))) {
- note ("Bad IP checksum: %x",
- wrapsum (checksum (buf + bufix, sizeof *ip, 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;
}
+ /* Check the IP packet length. */
+ if (ntohs (ip -> ip_len) != buflen)
+ debug ("ip length %d disagrees with bytes received %d.",
+ ntohs (ip -> ip_len), buflen);
+
/* Copy out the IP source address... */
memcpy (&from -> sin_addr, &ip -> ip_src, 4);
@@ -275,10 +251,25 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len)
if (!data) {
data = buf + bufix + ip_len + sizeof *udp;
- len -= 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.");
}
-#if 0
usum = udp -> uh_sum;
udp -> uh_sum = 0;
@@ -286,20 +277,25 @@ ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len)
checksum (data, len,
checksum ((unsigned char *)
&ip -> ip_src,
- sizeof ip -> ip_src,
+ 2 * sizeof ip -> ip_src,
IPPROTO_UDP +
(u_int32_t)
ntohs (udp -> uh_ulen)))));
+ udp_packets_seen++;
if (usum && usum != sum) {
- note ("Bad udp checksum: %x %x", 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;
}
-#endif
/* Copy out the port... */
memcpy (&from -> sin_port, &udp -> uh_sport, sizeof udp -> uh_sport);
return ip_len + sizeof *udp;
}
-#endif /* PACKET_DECODING */
diff --git a/usr.sbin/dhcp/common/parse.c b/usr.sbin/dhcp/common/parse.c
index 16390797650..0ffc4b09337 100644
--- a/usr.sbin/dhcp/common/parse.c
+++ b/usr.sbin/dhcp/common/parse.c
@@ -3,7 +3,7 @@
Common parser code for dhcpd and dhclient. */
/*
- * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,11 +40,6 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: parse.c,v 1.3 2001/01/03 16:04:39 ericj Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
#include "dhctoken.h"
@@ -127,7 +122,7 @@ char *parse_string (cfile)
s = (char *)malloc (strlen (val) + 1);
if (!s)
error ("no memory for string %s.", val);
- strcpy (s, val);
+ strlcpy (s, val, strlen(val) + 1);
if (!parse_semi (cfile))
return (char *)0;
@@ -158,7 +153,7 @@ char *parse_host_name (cfile)
/* Store this identifier... */
if (!(s = (char *)malloc (strlen (val) + 1)))
error ("can't allocate temp space for hostname.");
- strcpy (s, val);
+ strlcpy (s, val, strlen(val) + 1);
c = cons ((caddr_t)s, c);
len += strlen (s) + 1;
/* Look for a dot; if it's there, keep going, otherwise
@@ -219,6 +214,9 @@ void parse_hardware_param (cfile, hardware)
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);
@@ -244,6 +242,9 @@ void parse_hardware_param (cfile, hardware)
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);
}
@@ -277,24 +278,25 @@ void parse_lease_time (cfile, timep)
}
/* 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
+ this function does is to parse a sequence of numbers seperated by
+ the token specified in seperator. 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 (cfile, buf,
- max, separator, base, size)
+ max, seperator, base, size)
FILE *cfile;
unsigned char *buf;
int *max;
- int separator;
+ int seperator;
int base;
int size;
{
char *val;
int token;
- unsigned char *bufp = buf, *s, *t;
+ unsigned char *bufp = buf, *s = NULL;
+ char *t;
int count = 0;
pair c = (pair)0;
@@ -308,7 +310,7 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
do {
if (count) {
token = peek_token (&val, cfile);
- if (token != separator) {
+ if (token != seperator) {
if (!*max)
break;
if (token != RBRACE && token != LBRACE)
@@ -340,10 +342,10 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
convert_num (s, val, base, size);
s += size / 8;
} else {
- t = (unsigned char *)malloc (strlen (val) + 1);
+ t = (char *)malloc (strlen (val) + 1);
if (!t)
error ("no temp space for number.");
- strcpy (t, val);
+ strlcpy (t, val, strlen(val)+1);
c = cons (t, c);
}
} while (++count != *max);
@@ -516,10 +518,10 @@ TIME parse_date (cfile)
if (tm.tm_year > 1900)
tm.tm_year -= 1900;
- /* Slash separating year from month... */
+ /* Slash seperating year from month... */
token = next_token (&val, cfile);
if (token != SLASH) {
- parse_warn ("expected slash separating year from month.");
+ parse_warn ("expected slash seperating year from month.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
@@ -535,10 +537,10 @@ TIME parse_date (cfile)
}
tm.tm_mon = atoi (val) - 1;
- /* Slash separating month from day... */
+ /* Slash seperating month from day... */
token = next_token (&val, cfile);
if (token != SLASH) {
- parse_warn ("expected slash separating month from day.");
+ parse_warn ("expected slash seperating month from day.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
@@ -564,10 +566,10 @@ TIME parse_date (cfile)
}
tm.tm_hour = atoi (val);
- /* Colon separating hour from minute... */
+ /* Colon seperating hour from minute... */
token = next_token (&val, cfile);
if (token != COLON) {
- parse_warn ("expected colon separating hour from minute.");
+ parse_warn ("expected colon seperating hour from minute.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
@@ -583,10 +585,10 @@ TIME parse_date (cfile)
}
tm.tm_min = atoi (val);
- /* Colon separating minute from second... */
+ /* Colon seperating minute from second... */
token = next_token (&val, cfile);
if (token != COLON) {
- parse_warn ("expected colon separating hour from minute.");
+ parse_warn ("expected colon seperating hour from minute.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
diff --git a/usr.sbin/dhcp/common/print.c b/usr.sbin/dhcp/common/print.c
index 7ff64ffdd46..6d2becd5008 100644
--- a/usr.sbin/dhcp/common/print.c
+++ b/usr.sbin/dhcp/common/print.c
@@ -3,7 +3,7 @@
Turn data structures into printable text. */
/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,11 +40,6 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: print.c,v 1.1 1998/08/18 03:43:27 deraadt Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
char *print_hw_addr (htype, hlen, data)
@@ -59,10 +54,12 @@ char *print_hw_addr (htype, hlen, data)
if (htype == 0 || hlen == 0) {
strcpy (habuf, "<null>");
} else {
+ int slen = sizeof(habuf);
s = habuf;
for (i = 0; i < hlen; i++) {
- sprintf (s, "%02x", data [i]);
+ snprintf (s, slen, "%02x", data [i]);
s += strlen (s);
+ slen -= (strlen(s) + 1);
*s++ = ':';
}
*--s = 0;
@@ -76,26 +73,26 @@ void print_lease (lease)
struct tm *t;
char tbuf [32];
- debug (" Lease %s",
+ debug (" Lease %s",
piaddr (lease -> ip_addr));
t = gmtime (&lease -> starts);
- strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
- debug (" start %s", tbuf);
+ strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
+ debug (" start %s", tbuf);
t = gmtime (&lease -> ends);
- strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
- debug (" end %s", tbuf);
+ strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
+ debug (" end %s", tbuf);
t = gmtime (&lease -> timestamp);
- strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
- debug (" stamp %s", tbuf);
+ strftime (tbuf, sizeof tbuf, "%Y/%m/%d %H:%M:%S", t);
+ debug (" stamp %s", tbuf);
- debug (" hardware addr = %s",
+ debug (" hardware addr = %s",
print_hw_addr (lease -> hardware_addr.htype,
lease -> hardware_addr.hlen,
lease -> hardware_addr.haddr));
- debug (" host %s ",
+ debug (" host %s ",
lease -> host ? lease -> host -> name : "<none>");
}
@@ -141,8 +138,9 @@ void dump_raw (buf, len)
unsigned char *buf;
int len;
{
- int i;
+ int i, j;
char lbuf [80];
+ int llen = sizeof(lbuf);
int lbix = 0;
lbuf [0] = 0;
@@ -151,12 +149,16 @@ void dump_raw (buf, len)
if ((i & 15) == 0) {
if (lbix)
note (lbuf);
- sprintf (lbuf, "%03x:", i);
- lbix = 4;
- } else if ((i & 7) == 0)
+ j = snprintf (lbuf, llen, "%03x:", i);
+ lbix+=j;
+ llen-=j;
+ } else if ((i & 7) == 0) {
lbuf [lbix++] = ' ';
- sprintf (&lbuf [lbix], " %02x", buf [i]);
- lbix += 3;
+ len--;
+ }
+ j = snprintf (&lbuf [lbix], llen, " %02x", buf [i]);
+ lbix += j;
+ llen -= j;
}
note (lbuf);
}
@@ -178,7 +180,7 @@ void hash_dump (table)
if (bp -> len)
dump_raw (bp -> name, bp -> len);
else
- note (bp -> name);
+ note ((char *)bp -> name);
}
}
}
diff --git a/usr.sbin/dhcp/common/raw.c b/usr.sbin/dhcp/common/raw.c
deleted file mode 100644
index 38c53121500..00000000000
--- a/usr.sbin/dhcp/common/raw.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* socket.c
-
- BSD raw socket interface code... */
-
-/* XXX
-
- It's not clear how this should work, and that lack of clarity is
- terribly detrimental to the NetBSD 1.1 kernel - it crashes and
- burns.
-
- Using raw sockets ought to be a big win over using BPF or something
- like it, because you don't need to deal with the complexities of
- the physical layer, but it appears not to be possible with existing
- raw socket implementations. This may be worth revisiting in the
- future. For now, this code can probably be considered a curiosity.
- Sigh. */
-
-/*
- * 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''. */
-
-#ifndef lint
-static char copyright[] =
-"$Id: raw.c,v 1.1 1998/08/18 03:43:27 deraadt Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-#if defined (USE_RAW_SEND)
-#include <sys/uio.h>
-
-/* Generic interface registration routine... */
-void if_register_send (info)
- struct interface_info *info;
-{
- struct sockaddr_in name;
- int sock;
- struct socklist *tmp;
- int flag;
-
- /* Set up the address we're going to connect to. */
- name.sin_family = AF_INET;
- name.sin_port = local_port;
- name.sin_addr.s_addr = htonl (INADDR_BROADCAST);
- memset (name.sin_zero, 0, sizeof (name.sin_zero));
-
- /* List addresses on which we're listening. */
- if (!quiet_interface_discovery)
- note ("Sending on %s, port %d",
- piaddr (info -> address), htons (local_port));
- if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
- error ("Can't create dhcp socket: %m");
-
- /* Set the BROADCAST option so that we can broadcast DHCP responses. */
- flag = 1;
- if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
- &flag, sizeof flag) < 0)
- error ("Can't set SO_BROADCAST option on dhcp socket: %m");
-
- /* Set the IP_HDRINCL flag so that we can supply our own IP
- headers... */
- if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &flag, sizeof flag) < 0)
- error ("Can't set IP_HDRINCL flag: %m");
-
- info -> wfdesc = sock;
- if (!quiet_interface_discovery)
- note ("Sending on Raw/%s/%s",
- info -> name,
- (info -> shared_network ?
- info -> shared_network -> name : "unattached"));
-}
-
-size_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
- struct dhcp_packet *raw;
- size_t len;
- struct in_addr from;
- struct sockaddr_in *to;
- struct hardware *hto;
-{
- unsigned char buf [256];
- int bufp = 0;
- struct iovec iov [2];
-
- /* Assemble the headers... */
- assemble_udp_ip_header (interface, 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;
-
- return writev(interface -> wfdesc, iov, 2);
-}
-#endif /* USE_SOCKET_SEND */
diff --git a/usr.sbin/dhcp/common/resolv.c b/usr.sbin/dhcp/common/resolv.c
deleted file mode 100644
index a26608e40ee..00000000000
--- a/usr.sbin/dhcp/common/resolv.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* resolv.c
-
- Parser for /etc/resolv.conf 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''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: resolv.c,v 1.2 2001/01/03 16:04:39 ericj Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#include "dhctoken.h"
-
-struct name_server *name_servers;
-struct domain_search_list *domains;
-char path_resolv_conf [] = _PATH_RESOLV_CONF;
-
-void read_resolv_conf (parse_time)
- TIME parse_time;
-{
- FILE *cfile;
- char *val;
- int token;
- struct name_server *sp, *sl, *ns;
- struct domain_search_list *dp, *dl, *nd;
-
- new_parse (path_resolv_conf);
-
- eol_token = 1;
- if ((cfile = fopen (path_resolv_conf, "r")) == NULL) {
- warn ("Can't open %s: %m", path_resolv_conf);
- return;
- }
-
- do {
- token = next_token (&val, cfile);
- if (token == EOF)
- break;
- else if (token == EOL)
- continue;
- else if (token == DOMAIN || token == SEARCH) {
- do {
- struct domain_search_list *nd, **dp;
- char *dn;
-
- dn = parse_host_name (cfile);
- if (!dn)
- break;
-
- dp = &domains;
- for (nd = domains; nd; nd = nd -> next) {
- dp = &nd -> next;
- if (!strcmp (nd -> domain, dn))
- break;
- }
- if (!nd) {
- nd = new_domain_search_list
- ("read_resolv_conf");
- if (!nd)
- error ("No memory for %s", dn);
- nd -> next =
- (struct domain_search_list *)0;
- *dp = nd;
- nd -> domain = dn;
- dn = (char *)0;
- }
- nd -> rcdate = parse_time;
- token = peek_token (&val, cfile);
- } while (token != EOL);
- if (token != EOL) {
- parse_warn ("junk after domain declaration");
- skip_to_semi (cfile);
- }
- token = next_token (&val, cfile);
- } else if (token == NAMESERVER) {
- struct name_server *ns, **sp;
- struct iaddr iaddr;
-
- parse_ip_addr (cfile, &iaddr);
-
- sp = &name_servers;
- for (ns = name_servers; ns; ns = ns -> next) {
- sp = &ns -> next;
- if (!memcmp (&ns -> addr.sin_addr,
- iaddr.iabuf, iaddr.len))
- break;
- }
- if (!ns) {
- ns = new_name_server ("read_resolv_conf");
- if (!ns)
- error ("No memory for nameserver %s",
- piaddr (iaddr));
- ns -> next = (struct name_server *)0;
- *sp = ns;
- memcpy (&ns -> addr.sin_addr,
- iaddr.iabuf, iaddr.len);
-#ifdef HAVE_SA_LEN
- ns -> addr.sin_len = sizeof ns -> addr;
-#endif
- ns -> addr.sin_family = AF_INET;
- ns -> addr.sin_port = htons (53);
- memset (ns -> addr.sin_zero, 0,
- sizeof ns -> addr.sin_zero);
- }
- ns -> rcdate = parse_time;
- skip_to_semi (cfile);
- }
- } while (1);
- token = next_token (&val, cfile); /* Clear the peek buffer */
-
- /* Lose servers that are no longer in /etc/resolv.conf. */
- sl = (struct name_server *)0;
- for (sp = name_servers; sp; sp = ns) {
- ns = sp -> next;
- if (sp -> rcdate != parse_time) {
- if (sl)
- sl -> next = sp -> next;
- else
- name_servers = sp -> next;
- free_name_server (sp, "pick_name_server");
- } else
- sl = sp;
- }
-
- /* Lose domains that are no longer in /etc/resolv.conf. */
- dl = (struct domain_search_list *)0;
- for (dp = domains; dp; dp = nd) {
- nd = dp -> next;
- if (dp -> rcdate != parse_time) {
- if (dl)
- dl -> next = dp -> next;
- else
- domains = dp -> next;
- free_domain_search_list (dp, "pick_name_server");
- } else
- dl = dp;
- }
- eol_token = 0;
-}
-
-/* Pick a name server from the /etc/resolv.conf file. */
-
-struct sockaddr_in *pick_name_server ()
-{
- static TIME rcdate;
- struct stat st;
-
- /* Check /etc/resolv.conf and reload it if it's changed. */
- if (cur_time > rcdate) {
- if (stat (path_resolv_conf, &st) < 0) {
- warn ("Can't stat %s", path_resolv_conf);
- return (struct sockaddr_in *)0;
- }
- if (st.st_mtime > rcdate) {
- rcdate = cur_time + 1;
-
- read_resolv_conf (rcdate);
- }
- }
-
- if (name_servers)
- return &name_servers -> addr;
- return (struct sockaddr_in *)0;
-}
diff --git a/usr.sbin/dhcp/common/socket.c b/usr.sbin/dhcp/common/socket.c
index 2f19de70bd1..03aac4a4a9f 100644
--- a/usr.sbin/dhcp/common/socket.c
+++ b/usr.sbin/dhcp/common/socket.c
@@ -3,8 +3,8 @@
BSD socket interface code... */
/*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
- * All rights reserved.
+ * 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
@@ -40,60 +40,8 @@
* Enterprises, see ``http://www.vix.com''.
*/
-/* SO_BINDTODEVICE support added by Elliot Poger (poger@leland.stanford.edu).
- * This sockopt allows a socket to be bound to a particular interface,
- * thus enabling the use of DHCPD on a multihomed host.
- * If SO_BINDTODEVICE is defined in your system header files, the use of
- * this sockopt will be automatically enabled.
- * I have implemented it under Linux; other systems should be doable also.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: socket.c,v 1.2 2000/12/30 17:54:07 angelos Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
-#ifdef USE_SOCKET_FALLBACK
-# define USE_SOCKET_SEND
-# define if_register_send if_register_fallback
-# define send_packet send_fallback
-# define if_reinitialize_send if_reinitialize_fallback
-#endif
-
-static int once = 0;
-
-/* Reinitializes the specified interface after an address change. This
- is not required for packet-filter APIs. */
-
-#ifdef USE_SOCKET_SEND
-void if_reinitialize_send (info)
- struct interface_info *info;
-{
-#if 0
-#ifndef USE_SOCKET_RECEIVE
- once = 0;
- close (info -> wfdesc);
-#endif
- if_register_send (info);
-#endif
-}
-#endif
-
-#ifdef USE_SOCKET_RECEIVE
-void if_reinitialize_receive (info)
- struct interface_info *info;
-{
-#if 0
- once = 0;
- close (info -> rfdesc);
- if_register_receive (info);
-#endif
-}
-#endif
-
-#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE)
/* Generic interface registration routine... */
int if_register_socket (info)
struct interface_info *info;
@@ -102,14 +50,6 @@ int if_register_socket (info)
int sock;
int flag;
-#ifndef SO_BINDTODEVICE
- /* Make sure only one interface is registered. */
- if (once)
- error ("The standard socket API can only support %s",
- "hosts with a single network interface.");
- once = 1;
-#endif
-
/* Set up the address we're going to bind to. */
name.sin_family = AF_INET;
name.sin_port = local_port;
@@ -130,7 +70,7 @@ int if_register_socket (info)
flag = 1;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEPORT,
(char *)&flag, sizeof flag) < 0)
- error ("Can't set SO_REUSEPORT option on dhcp socket: %m");
+ error ("Can't set SO_REUSEPORT option on dhcp socket: %m");
/* Set the BROADCAST option so that we can broadcast DHCP responses. */
if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
@@ -141,53 +81,24 @@ int if_register_socket (info)
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
error ("Can't bind to dhcp address: %m");
-#ifdef SO_BINDTODEVICE
- /* Bind this socket to this interface. */
- if (setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
- (char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
- error("setting SO_BINDTODEVICE");
- }
-#endif
-
return sock;
}
-#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
-#ifdef USE_SOCKET_SEND
-void if_register_send (info)
+void if_register_fallback (info)
struct interface_info *info;
{
-#ifndef USE_SOCKET_RECEIVE
- info -> wfdesc = if_register_socket (info);
-#else
- info -> wfdesc = info -> rfdesc;
-#endif
- if (!quiet_interface_discovery)
- note ("Sending on Socket/%s/%s",
- info -> name,
- (info -> shared_network ?
- info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_SOCKET_SEND */
+ info -> wfdesc = if_register_socket (info);
-#ifdef USE_SOCKET_RECEIVE
-void if_register_receive (info)
- struct interface_info *info;
-{
- /* If we're using the socket API for sending and receiving,
- we don't need to register this interface twice. */
- info -> rfdesc = if_register_socket (info);
if (!quiet_interface_discovery)
- note ("Listening on Socket/%s/%s",
+ note ("Sending on Socket/%s%s%s",
info -> name,
+ (info -> shared_network ? "/" : ""),
(info -> shared_network ?
- info -> shared_network -> name : "unattached"));
+ info -> shared_network -> name : ""));
}
-#endif /* USE_SOCKET_RECEIVE */
-#ifdef USE_SOCKET_SEND
-ssize_t send_packet (interface, packet, raw, len, from, to, hto)
+ssize_t send_fallback (interface, packet, raw, len, from, to, hto)
struct interface_info *interface;
struct packet *packet;
struct dhcp_packet *raw;
@@ -197,51 +108,19 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct hardware *hto;
{
int result;
-#ifdef IGNORE_HOSTUNREACH
- int retry = 0;
- do {
-#endif
- result = sendto (interface -> wfdesc, (char *)raw, len, 0,
- (struct sockaddr *)to, sizeof *to);
-#ifdef IGNORE_HOSTUNREACH
- } while (to -> sin_addr.s_addr == htonl (INADDR_BROADCAST) &&
- result < 0 &&
- (errno == EHOSTUNREACH ||
- errno == ECONNREFUSED) &&
- retry++ < 10);
-#endif
- return result;
-}
-#endif /* USE_SOCKET_SEND */
-#ifdef USE_SOCKET_RECEIVE
-ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
- size_t len;
- struct sockaddr_in *from;
- struct hardware *hfrom;
-{
- int flen = sizeof *from;
- int result;
+ result = sendto (interface -> wfdesc, (char *)raw, len, 0,
+ (struct sockaddr *)to, sizeof *to);
-#ifdef IGNORE_HOSTUNREACH
- int retry = 0;
- do {
-#endif
- result = recvfrom (interface -> rfdesc, buf, len, 0,
- (struct sockaddr *)from, &flen);
-#ifdef IGNORE_HOSTUNREACH
- } while (result < 0 &&
- (errno == EHOSTUNREACH ||
- errno == ECONNREFUSED) &&
- retry++ < 10);
-#endif
+ if (result == -1) {
+ warn ("send_fallback: %m");
+ if (errno == ENETUNREACH)
+ warn ("send_fallback: please consult README file %s",
+ "regarding broadcast address.");
+ }
return result;
}
-#endif /* USE_SOCKET_RECEIVE */
-#ifdef USE_SOCKET_FALLBACK
/* This just reads in a packet and silently discards it. */
void fallback_discard (protocol)
@@ -255,7 +134,6 @@ void fallback_discard (protocol)
status = recvfrom (interface -> wfdesc, buf, sizeof buf, 0,
(struct sockaddr *)&from, &flen);
- if (status < 0)
+ if (status == 0)
warn ("fallback_discard: %m");
}
-#endif /* USE_SOCKET_RECEIVE */
diff --git a/usr.sbin/dhcp/common/sysconf.c b/usr.sbin/dhcp/common/sysconf.c
deleted file mode 100644
index 98cbb1073cf..00000000000
--- a/usr.sbin/dhcp/common/sysconf.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* sysconf.c
-
- System status watcher...
-
- !!!Boy, howdy, is this ever not guaranteed not to change!!! */
-
-/*
- * 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''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: sysconf.c,v 1.1 1998/08/18 03:43:27 deraadt Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-
-int sysconf_initialized;
-int sysconf_fd;
-
-void sysconf_startup (handler)
- void (*handler) PROTO ((struct sysconf_header *, void *));
-{
- struct sockaddr_un name;
- static int once;
-
- /* Only initialize sysconf once. */
- if (sysconf_initialized)
- error ("attempted to reinitialize sysconf protocol");
- sysconf_initialized = 1;
-
- sysconf_fd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (sysconf_fd < 0)
- error ("unable to create sysconf socket: %m");
-
- /* XXX for now... */
- name.sun_family = PF_UNIX;
- strcpy (name.sun_path, "/var/run/sysconf");
- name.sun_len = ((sizeof name) - (sizeof name.sun_path) +
- strlen (name.sun_path));
-
- if (connect (sysconf_fd, (struct sockaddr *)&name, name.sun_len) < 0) {
- if (!once)
- warn ("can't connect to sysconf socket: %m");
- once = 1;
- close (sysconf_fd);
- sysconf_initialized = 0;
- add_timeout (cur_time + 60, sysconf_restart, handler);
- } else
- add_protocol ("sysconf", sysconf_fd, sysconf_message, handler);
-}
-
-void sysconf_restart (v)
- void *v;
-{
- void (*handler) PROTO ((struct sysconf_header *, void *)) = v;
-
- sysconf_startup (handler);
-}
-
-void sysconf_message (proto)
- struct protocol *proto;
-{
- struct sysconf_header hdr;
- int status;
- char *buf;
- void (*handler) PROTO ((struct sysconf_header *, void *));
-
- status = read (sysconf_fd, &hdr, sizeof hdr);
- if (status < 0) {
- warn ("sysconf_message: %m");
- lose:
- add_timeout (cur_time + 60, sysconf_restart, proto -> local);
- remove_protocol (proto);
- return;
- }
- if (status < sizeof (hdr)) {
- warn ("sysconf_message: short message");
- goto lose;
- }
-
- if (hdr.length) {
- buf = malloc (hdr.length);
- if (!buf)
- error ("sysconf_message: can't buffer payload");
- status = read (sysconf_fd, buf, hdr.length);
- if (status < 0)
- error ("sysconf_message payload read: %m");
- if (status != hdr.length)
- error ("sysconf_message payload: short read");
- } else
- buf = (char *)0;
-
- /* Call the handler... */
- if ((handler = proto -> local))
- (*handler) (&hdr, buf);
-
- if (buf)
- free (buf);
-}
diff --git a/usr.sbin/dhcp/common/tables.c b/usr.sbin/dhcp/common/tables.c
index 454962a0857..d336516c01c 100644
--- a/usr.sbin/dhcp/common/tables.c
+++ b/usr.sbin/dhcp/common/tables.c
@@ -40,11 +40,6 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: tables.c,v 1.1 1998/08/18 03:43:27 deraadt Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
/* DHCP Option names, formats and codes, from RFC1533.
@@ -78,7 +73,7 @@ struct option dhcp_options [256] = {
{ "lpr-servers", "IA", &dhcp_universe, 9 },
{ "impress-servers", "IA", &dhcp_universe, 10 },
{ "resource-location-servers", "IA", &dhcp_universe, 11 },
- { "host-name", "t", &dhcp_universe, 12 },
+ { "host-name", "X", &dhcp_universe, 12 },
{ "boot-size", "S", &dhcp_universe, 13 },
{ "merit-dump", "t", &dhcp_universe, 14 },
{ "domain-name", "t", &dhcp_universe, 15 },
@@ -130,20 +125,20 @@ struct option dhcp_options [256] = {
{ "dhcp-client-identifier", "X", &dhcp_universe, 61 },
{ "option-62", "X", &dhcp_universe, 62 },
{ "option-63", "X", &dhcp_universe, 63 },
- { "option-64", "X", &dhcp_universe, 64 },
- { "option-65", "X", &dhcp_universe, 65 },
- { "option-66", "X", &dhcp_universe, 66 },
- { "option-67", "X", &dhcp_universe, 67 },
- { "option-68", "X", &dhcp_universe, 68 },
- { "option-69", "X", &dhcp_universe, 69 },
- { "option-70", "X", &dhcp_universe, 70 },
- { "option-71", "X", &dhcp_universe, 71 },
- { "option-72", "X", &dhcp_universe, 72 },
- { "option-73", "X", &dhcp_universe, 73 },
- { "option-74", "X", &dhcp_universe, 74 },
- { "option-75", "X", &dhcp_universe, 75 },
- { "option-76", "X", &dhcp_universe, 76 },
- { "dhcp-user-class-identifier", "t", &dhcp_universe, 77 },
+ { "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 },
@@ -418,7 +413,7 @@ char *hardware_types [] = {
"unknown-5",
"token-ring",
"unknown-7",
- "unknown-8",
+ "fddi",
"unknown-9",
"unknown-10",
"unknown-11",
@@ -681,10 +676,12 @@ void initialize_universes()
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, dhcp_options [i].name, 0,
+ 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, dhcp_universe.name, 0,
+ add_hash (&universe_hash,
+ (unsigned char *)dhcp_universe.name, 0,
(unsigned char *)&dhcp_universe);
}
diff --git a/usr.sbin/dhcp/common/tree.c b/usr.sbin/dhcp/common/tree.c
index aeb48d13026..0fdc4e53fba 100644
--- a/usr.sbin/dhcp/common/tree.c
+++ b/usr.sbin/dhcp/common/tree.c
@@ -40,11 +40,6 @@
* Enterprises, see ``http://www.vix.com''.
*/
-#ifndef lint
-static char copyright[] =
-"$Id: tree.c,v 1.1 1998/08/18 03:43:27 deraadt Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
#include "dhcpd.h"
static TIME tree_evaluate_recurse PROTO ((int *, unsigned char **, int *,
@@ -313,13 +308,10 @@ static TIME do_host_lookup (bufix, bufp, bufcount, dns)
/* Otherwise, look it up... */
h = gethostbyname (dns -> hostname);
- if (!h) {
-#ifndef NO_H_ERRNO
+ if (h != NULL) {
switch (h_errno) {
case HOST_NOT_FOUND:
-#endif
warn ("%s: host unknown.", dns -> hostname);
-#ifndef NO_H_ERRNO
break;
case TRY_AGAIN:
warn ("%s: temporary name server failure",
@@ -332,8 +324,6 @@ static TIME do_host_lookup (bufix, bufp, bufcount, dns)
warn ("%s: no A record associated with address",
dns -> hostname);
}
-#endif /* !NO_H_ERRNO */
-
/* Okay to try again after a minute. */
return cur_time + 60;
}
diff --git a/usr.sbin/dhcp/common/upf.c b/usr.sbin/dhcp/common/upf.c
deleted file mode 100644
index a83ac5bf9c6..00000000000
--- a/usr.sbin/dhcp/common/upf.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/* upf.c
- *
- * Ultrix PacketFilter interface code.
- */
-
-/*
- * 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''.
- */
-
-#ifndef lint
-static char copyright[] =
-"$Id: upf.c,v 1.2 2001/01/03 16:04:39 ericj Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
-#endif /* not lint */
-
-#include "dhcpd.h"
-#if defined (USE_UPF_SEND) || defined (USE_UPF_RECEIVE)
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include <net/pfilt.h>
-#include <netinet/in_systm.h>
-#include "includes/netinet/ip.h"
-#include "includes/netinet/udp.h"
-#include "includes/netinet/if_ether.h"
-
-/* Reinitializes the specified interface after an address change. This
- is not required for packet-filter APIs. */
-
-#ifdef USE_UPF_SEND
-void if_reinitialize_send (info)
- struct interface_info *info;
-{
-}
-#endif
-
-#ifdef USE_UPF_RECEIVE
-void if_reinitialize_receive (info)
- struct interface_info *info;
-{
-}
-#endif
-
-/* 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_upf (info)
- struct interface_info *info;
-{
- int sock;
- char filename[50];
- int b;
- struct endevp param;
-
- /* Open a UPF device */
- for (b = 0; 1; b++) {
-#ifndef NO_SNPRINTF
- snprintf(filename, sizeof(filename), "/dev/pf/pfilt%d", b);
-#else
- sprintf(filename, "/dev/pf/pfilt%d", b);
-#endif
- sock = open (filename, O_RDWR, 0);
- if (sock < 0) {
- if (errno == EBUSY) {
- continue;
- } else {
- error ("Can't find free upf: %m");
- }
- } else {
- break;
- }
- }
-
- /* Set the UPF device to point at this interface. */
- if (ioctl (sock, EIOCSETIF, info -> ifp) < 0)
- error ("Can't attach interface %s to upf device %s: %m",
- info -> name, filename);
-
- /* Get the hardware address. */
- if (ioctl (sock, EIOCDEVP, &param) < 0)
- error ("Can't get interface %s hardware address: %m",
- info -> name);
-
- /* We only know how to do ethernet. */
- if (param.end_dev_type != ENDT_10MB)
- error ("Invalid device type on network interface %s: %d",
- info -> name, param.end_dev_type);
-
- if (param.end_addr_len != 6)
- error ("Invalid hardware address length on %s: %d",
- info -> name, param.end_addr_len);
-
- info -> hw_address.hlen = 6;
- info -> hw_address.htype = ARPHRD_ETHER;
- memcpy (&info -> hw_address.haddr [0], param.end_addr, 6);
-
- return sock;
-}
-#endif /* USE_UPF_SEND || USE_UPF_RECEIVE */
-
-#ifdef USE_UPF_SEND
-void if_register_send (info)
- struct interface_info *info;
-{
- /* If we're using the upf API for sending and receiving,
- we don't need to register this interface twice. */
-#ifndef USE_UPF_RECEIVE
- info -> wfdesc = if_register_upf (info, interface);
-#else
- info -> wfdesc = info -> rfdesc;
-#endif
- if (!quiet_interface_discovery)
- note ("Sending on UPF/%s/%s/%s",
- info -> name,
- print_hw_addr (info -> hw_address.htype,
- info -> hw_address.hlen,
- info -> hw_address.haddr),
- (info -> shared_network ?
- info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_UPF_SEND */
-
-#ifdef USE_UPF_RECEIVE
-/* Packet filter program...
- XXX Changes to the filter program may require changes to the constant
- offsets used in if_register_send to patch the UPF program! XXX */
-
-
-void if_register_receive (info)
- struct interface_info *info;
-{
- int flag = 1;
- u_int32_t addr;
- struct enfilter pf;
- u_int32_t bits;
-
- /* Open a UPF device and hang it on this interface... */
- info -> rfdesc = if_register_upf (info);
-
- /* Allow the copyall flag to be set... */
- if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
- error ("Can't set ALLOWCOPYALL: %m");
-
- /* Clear all the packet filter mode bits first... */
- flag = (ENHOLDSIG | ENBATCH | ENTSTAMP | ENPROMISC |
- ENNONEXCL | ENCOPYALL);
- if (ioctl (info -> rfdesc, EIOCMBIC, &flag) < 0)
- error ("Can't clear pfilt bits: %m");
-
- /* Set the ENBATCH and ENCOPYALL bits... */
- bits = ENBATCH | ENCOPYALL;
- if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
- error ("Can't set ENBATCH|ENCOPYALL: %m");
-
- /* Set up the UPF filter program. */
- /* XXX Unlike the BPF filter program, this one won't work if the
- XXX IP packet is fragmented or if there are options on the IP
- XXX header. */
- pf.enf_Priority = 0;
- pf.enf_FilterLen = 0;
-
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 6;
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
- pf.enf_Filter [pf.enf_FilterLen++] = htons (ETHERTYPE_IP);
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT;
- pf.enf_Filter [pf.enf_FilterLen++] = htons (IPPROTO_UDP);
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 11;
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
- pf.enf_Filter [pf.enf_FilterLen++] = htons (0xFF);
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_CAND;
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 18;
- pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
- pf.enf_Filter [pf.enf_FilterLen++] = local_port;
-
- if (ioctl (info -> rfdesc, EIOCSETF, &pf) < 0)
- error ("Can't install packet filter program: %m");
- if (!quiet_interface_discovery)
- note ("Listening on UPF/%s/%s/%s",
- info -> name,
- print_hw_addr (info -> hw_address.htype,
- info -> hw_address.hlen,
- info -> hw_address.haddr),
- (info -> shared_network ?
- info -> shared_network -> name : "unattached"));
-}
-#endif /* USE_UPF_RECEIVE */
-
-#ifdef USE_UPF_SEND
-ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
- struct dhcp_packet *raw;
- size_t len;
- struct in_addr from;
- struct sockaddr_in *to;
- struct hardware *hto;
-{
- int bufp = 0;
- unsigned char buf [256];
- struct iovec iov [2];
-
- /* Assemble the headers... */
- assemble_hw_header (interface, buf, &bufp, hto);
- assemble_udp_ip_header (interface, 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;
-
- return writev(interface -> wfdesc, iov, 2);
-}
-#endif /* USE_UPF_SEND */
-
-#ifdef USE_UPF_RECEIVE
-ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
- size_t len;
- struct sockaddr_in *from;
- struct hardware *hfrom;
-{
- int nread;
- int length = 0;
- int offset = 0;
- unsigned char ibuf [1500 + sizeof (struct enstamp)];
- int bufix = 0;
-
- length = read (interface -> rfdesc, ibuf, sizeof ibuf);
- if (length <= 0)
- return length;
-
- bufix = sizeof (struct enstamp);
- /* Decode the physical header... */
- offset = decode_hw_header (interface, ibuf, bufix, hfrom);
-
- /* If a physical layer checksum failed (dunno of any
- physical layer that supports this, but WTH), skip this
- packet. */
- if (offset < 0) {
- return 0;
- }
-
- bufix += offset;
- length -= offset;
-
- /* Decode the IP and UDP headers... */
- offset = decode_udp_ip_header (interface, ibuf, bufix,
- from, (unsigned char *)0, length);
-
- /* If the IP or UDP checksum was bad, skip the packet... */
- if (offset < 0)
- return 0;
-
- bufix += offset;
- length -= offset;
-
- /* Copy out the data in the packet... */
- memcpy (buf, &ibuf [bufix], length);
- return length;
-}
-#endif