Commit 6ceb9118 authored by Ted Lemon's avatar Ted Lemon
Browse files

Reference count binding scopes. Align IP headers on output.

parent a8c190df
......@@ -41,7 +41,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhclient.c,v 1.109 2000/07/20 03:21:23 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 Internet Software Consortium. All rights reserved.\n";
"$Id: dhclient.c,v 1.110 2000/07/27 09:02:23 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -65,8 +65,6 @@ struct in_addr inaddr_any;
struct sockaddr_in sockaddr_broadcast;
struct in_addr giaddr;
struct binding_scope global_scope;
/* ASSERT_STATE() does nothing now; it used to be
assert (state_is == state_shouldbe). */
#define ASSERT_STATE(state_is, state_shouldbe) {}
......@@ -74,8 +72,7 @@ struct binding_scope global_scope;
static char copyright[] = "Copyright 1995-2000 Internet Software Consortium.";
static char arr [] = "All rights reserved.";
static char message [] = "Internet Software Consortium DHCP Client";
static char contrib [] = "\nPlease contribute if you find this software useful.";
static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.html\n";
static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.html";
u_int16_t local_port;
u_int16_t remote_port;
......@@ -229,7 +226,6 @@ int main (argc, argv, envp)
log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright);
log_info (arr);
log_info (contrib);
log_info (url);
} else
log_perror = 0;
......@@ -661,7 +657,7 @@ void dhcpack (packet)
log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
lease = packet_to_lease (packet);
lease = packet_to_lease (packet, client);
if (!lease) {
log_info ("packet_to_lease failed.");
return;
......@@ -1010,7 +1006,7 @@ void dhcpoffer (packet)
}
}
lease = packet_to_lease (packet);
lease = packet_to_lease (packet, client);
if (!lease) {
log_info ("packet_to_lease failed.");
return;
......@@ -1063,8 +1059,9 @@ void dhcpoffer (packet)
/* Allocate a client_lease structure and initialize it from the parameters
in the specified packet. */
struct client_lease *packet_to_lease (packet)
struct client_lease *packet_to_lease (packet, client)
struct packet *packet;
struct client_state *client;
{
struct client_lease *lease;
int i;
......@@ -2370,7 +2367,7 @@ void client_envadd (struct client_state *client,
int dhcp_option_ev_name (buf, buflen, option)
char *buf;
unsigned buflen;
size_t buflen;
struct option *option;
{
int i;
......
......@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: alloc.c,v 1.48 2000/06/24 06:16:28 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: alloc.c,v 1.49 2000/07/27 09:02:28 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -1257,7 +1257,36 @@ int binding_scope_allocate (ptr, file, line)
if (!bp)
return 0;
memset (bp, 0, sizeof *bp);
binding_scope_reference (ptr, bp, file, line);
return 1;
}
int binding_scope_reference (ptr, bp, file, line)
struct binding_scope **ptr;
struct binding_scope *bp;
const char *file;
int line;
{
if (!ptr) {
log_error ("%s(%d): null pointer", file, line);
#if defined (POINTER_DEBUG)
abort ();
#else
return 0;
#endif
}
if (*ptr) {
log_error ("%s(%d): non-null pointer", file, line);
#if defined (POINTER_DEBUG)
abort ();
#else
*ptr = (struct binding_scope *)0;
#endif
}
*ptr = bp;
bp -> refcnt++;
rc_register (file, line, ptr, bp, bp -> refcnt);
dmalloc_reuse (bp, file, line, 1);
return 1;
}
......
......@@ -47,7 +47,7 @@
#ifndef lint
static char copyright[] =
"$Id: bpf.c,v 1.40 2000/06/08 21:14:10 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: bpf.c,v 1.41 2000/07/27 09:02:29 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -359,28 +359,33 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct sockaddr_in *to;
struct hardware *hto;
{
unsigned bufp = 0;
unsigned char buf [256];
struct iovec iov [2];
unsigned hbufp = 0, ibufp = 0;
double hw [4];
double ip [32];
struct iovec iov [3];
int result;
int fudge;
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);
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
assemble_hw_header (interface, (unsigned char *)hw, &hbufp, hto);
assemble_udp_ip_header (interface,
(unsigned char *)ip, &ibufp, from.s_addr,
to -> sin_addr.s_addr, to -> sin_port,
(unsigned char *)raw, len);
/* Fire it off */
iov [0].iov_base = (char *)buf;
iov [0].iov_len = bufp;
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
result = writev(interface -> wfdesc, iov, 2);
iov [0].iov_base = ((char *)hw);
iov [0].iov_len = hbufp;
iov [1].iov_base = ((char *)ip);
iov [1].iov_len = ibufp;
iov [2].iov_base = (char *)raw;
iov [2].iov_len = len;
result = writev(interface -> wfdesc, iov, 3);
if (result < 0)
log_error ("send_packet: %m");
return result;
......
......@@ -84,7 +84,7 @@
#ifndef lint
static char copyright[] =
"$Id: dlpi.c,v 1.21 2000/06/08 21:14:13 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: dlpi.c,v 1.22 2000/07/27 09:02:31 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -508,13 +508,17 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct sockaddr_in *to;
struct hardware *hto;
{
unsigned hbufp = 0;
double hh [16];
double ih [1536 / sizeof (double)];
unsigned char *dbuf = (unsigned char *)ih;
unsigned dbuflen;
unsigned char dbuf [1536];
unsigned char sap [2];
unsigned char dstaddr [DLPI_MAXDLADDR];
unsigned addrlen;
int saplen;
int result;
int fudge;
if (!strcmp (interface -> name, "fallback"))
return send_fallback (interface, packet, raw,
......@@ -524,7 +528,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
/* Assemble the headers... */
#ifdef USE_DLPI_RAW
assemble_hw_header (interface, dbuf, &dbuflen, hto);
assemble_hw_header (interface, (unsigned char *)hh, &dbuflen, hto);
fudge = dbuflen % 4; /* IP header must be word-aligned. */
memcpy (dbuf + fudge, (unsigned char *)hh, dbuflen);
#else
fudge = 0;
#endif
assemble_udp_ip_header (interface, dbuf, &dbuflen, from.s_addr,
to -> sin_addr.s_addr, to -> sin_port,
......@@ -535,7 +543,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
dbuflen += len;
#ifdef USE_DLPI_RAW
result = write (interface -> wfdesc, dbuf, dbuflen);
result = write (interface -> wfdesc, dbuf + fudge, dbuflen - fudge);
#else
/* XXX: Assumes ethernet, with two byte SAP */
sap [0] = 0x08; /* ETHERTYPE_IP, high byte */
......
......@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: execute.c,v 1.35 2000/07/06 22:42:22 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: execute.c,v 1.36 2000/07/27 09:02:32 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -55,7 +55,7 @@ int execute_statements (packet, lease, in_options, out_options, scope,
struct lease *lease;
struct option_state *in_options;
struct option_state *out_options;
struct binding_scope *scope;
struct binding_scope **scope;
struct executable_statement *statements;
{
struct executable_statement *r, *e, *next;
......@@ -163,9 +163,9 @@ int execute_statements (packet, lease, in_options, out_options, scope,
break;
case if_statement:
status = evaluate_boolean_expression
(&result, packet, lease, in_options,
out_options, scope, r -> data.ie.expr);
status = (evaluate_boolean_expression
(&result, packet, lease, in_options,
out_options, scope, r -> data.ie.expr));
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: if %s", (status
......@@ -244,7 +244,21 @@ int execute_statements (packet, lease, in_options, out_options, scope,
break;
case set_statement:
binding = find_binding (scope, r -> data.set.name);
if (!scope) {
log_error ("set %s: no scope",
r -> data.set.name);
status = 0;
break;
}
if (!*scope) {
if (!binding_scope_allocate (scope, MDL)) {
log_error ("set %s: can't allocate scope",
r -> data.set.name);
status = 0;
break;
}
}
binding = find_binding (*scope, r -> data.set.name);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: set %s", r -> data.set.name);
#endif
......@@ -261,12 +275,9 @@ int execute_statements (packet, lease, in_options, out_options, scope,
r -> data.set.name);
if (lease) {
binding -> next =
lease -> scope.bindings;
lease -> scope.bindings = binding;
} else {
binding -> next =
global_scope.bindings;
global_scope.bindings = binding;
lease -> scope -> bindings;
lease -> scope -> bindings =
binding;
}
} else {
badalloc:
......@@ -291,7 +302,11 @@ int execute_statements (packet, lease, in_options, out_options, scope,
break;
case unset_statement:
binding = find_binding (scope, r -> data.unset);
if (!scope || !*scope) {
status = 0;
break;
}
binding = find_binding (*scope, r -> data.unset);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("exec: unset %s", r -> data.unset);
#endif
......@@ -357,10 +372,12 @@ int execute_statements (packet, lease, in_options, out_options, scope,
e = e -> data.let.statements;
goto next_let;
} else if (ns) {
ns -> outer = scope;
if (scope && *scope)
binding_scope_reference (&ns -> outer,
*scope, MDL);
execute_statements
(packet, lease, in_options, out_options,
ns, e -> data.let.statements);
&ns, e -> data.let.statements);
}
if (ns)
binding_scope_dereference (&ns, MDL);
......@@ -392,7 +409,7 @@ void execute_statements_in_scope (packet, lease, in_options, out_options,
struct lease *lease;
struct option_state *in_options;
struct option_state *out_options;
struct binding_scope *scope;
struct binding_scope **scope;
struct group *group;
struct group *limiting_group;
{
......@@ -771,7 +788,7 @@ int find_matching_case (struct executable_statement **ep,
struct packet *packet, struct lease *lease,
struct option_state *in_options,
struct option_state *out_options,
struct binding_scope *scope,
struct binding_scope **scope,
struct expression *expr,
struct executable_statement *stmt)
{
......
......@@ -37,7 +37,7 @@
#ifndef lint
static char copyright[] =
"$Id: lpf.c,v 1.25 2000/06/08 21:14:14 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: lpf.c,v 1.26 2000/07/27 09:02:33 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -83,14 +83,18 @@ int if_register_lpf (info)
struct sockaddr sa;
/* Make an LPF socket. */
if ((sock = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
if ((sock = socket(PF_PACKET, SOCK_PACKET,
htons((short)ETH_P_ALL))) < 0) {
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
errno == EAFNOSUPPORT || errno == EINVAL)
log_fatal ("socket: %m - make sure %s %s %s!",
"CONFIG_PACKET (Packet socket)"
"and CONFIG_FILTER (Socket Filtering) are",
"enabled in your kernel configuration");
errno == EAFNOSUPPORT || errno == EINVAL) {
log_error ("socket: %m - make sure");
log_error ("CONFIG_PACKET (Packet socket) %s",
"and CONFIG_FILTER");
log_error ("(Socket Filtering) are enabled %s",
"in your kernel");
log_fatal ("configuration!");
}
log_fatal ("Open a socket for LPF: %m");
}
......@@ -101,11 +105,14 @@ int if_register_lpf (info)
if (bind (sock, &sa, sizeof sa)) {
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
errno == EAFNOSUPPORT || errno == EINVAL)
log_fatal ("socket: %m - make sure %s %s %s!",
"CONFIG_PACKET (Packet socket)"
"and CONFIG_FILTER (Socket Filtering) are",
"enabled in your kernel configuration");
errno == EAFNOSUPPORT || errno == EINVAL) {
log_error ("socket: %m - make sure");
log_error ("CONFIG_PACKET (Packet socket) %s",
"and CONFIG_FILTER");
log_error ("(Socket Filtering) are enabled %s",
"in your kernel");
log_fatal ("configuration!");
}
log_fatal ("Bind socket to interface: %m");
}
......@@ -222,17 +229,20 @@ static void lpf_gen_filter_setup (info)
/* Patch the server port into the LPF program...
XXX changes to filter program may require changes
to the insn number(s) used below! XXX */
dhcp_bpf_filter [8].k = ntohs (local_port);
dhcp_bpf_filter [8].k = ntohs ((short)local_port);
if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
sizeof p) < 0) {
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
errno == EAFNOSUPPORT)
log_fatal ("socket: %m - make sure %s %s %s!",
"CONFIG_PACKET (Packet socket)"
"and CONFIG_FILTER (Socket Filtering) are",
"enabled in your kernel configuration");
errno == EAFNOSUPPORT) {
log_error ("socket: %m - make sure");
log_error ("CONFIG_PACKET (Packet socket) %s",
"and CONFIG_FILTER");
log_error ("(Socket Filtering) are enabled %s",
"in your kernel");
log_fatal ("configuration!");
}
log_fatal ("Can't install packet filter program: %m");
}
}
......@@ -258,11 +268,14 @@ static void lpf_tr_filter_setup (info)
sizeof p) < 0) {
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
errno == EAFNOSUPPORT)
log_fatal ("socket: %m - make sure %s %s %s!",
"CONFIG_PACKET (Packet socket)"
"and CONFIG_FILTER (Socket Filtering) are",
"enabled in your kernel configuration");
errno == EAFNOSUPPORT) {
log_error ("socket: %m - make sure");
log_error ("CONFIG_PACKET (Packet socket) %s",
"and CONFIG_FILTER");
log_error ("(Socket Filtering) are enabled %s",
"in your kernel");
log_fatal ("configuration!");
}
log_fatal ("Can't install packet filter program: %m");
}
}
......@@ -278,21 +291,27 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct sockaddr_in *to;
struct hardware *hto;
{
unsigned bufp = 0;
unsigned char buf [1500];
unsigned hbufp = 0, ibufp = 0;
double hh [16];
double ih [1536 / sizeof (double)];
unsigned char *buf = (unsigned char *)ih;
struct sockaddr sa;
int result;
int fudge;
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);
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto);
fudge = hbufp % 4; /* IP header must be word-aligned. */
memcpy (buf + fudge, (unsigned char *)hh, hbufp);
ibufp = hbufp + fudge;
assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
to -> sin_addr.s_addr, to -> sin_port,
(unsigned char *)raw, len);
memcpy (buf + bufp, raw, len);
memcpy (buf + ibufp, raw, len);
/* For some reason, SOCK_PACKET sockets can't be connected,
so we have to do a sentdo every time. */
......@@ -301,8 +320,8 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
strncpy (sa.sa_data,
(const char *)interface -> ifp, sizeof sa.sa_data);
result = sendto (interface -> wfdesc, buf, bufp + len, 0,
&sa, sizeof sa);
result = sendto (interface -> wfdesc,
buf + fudge, ibufp + len - fudge, 0, &sa, sizeof sa);
if (result < 0)
log_error ("send_packet: %m");
return result;
......@@ -321,7 +340,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
int length = 0;
int offset = 0;
unsigned char ibuf [1500];
int bufix = 0;
unsigned bufix = 0;
length = read (interface -> rfdesc, ibuf, sizeof ibuf);
if (length <= 0)
......@@ -342,8 +361,8 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
length -= offset;
/* Decode the IP and UDP headers... */
offset = decode_udp_ip_header (interface, ibuf, bufix,
from, (unsigned char *)0, length);
offset = decode_udp_ip_header (interface, ibuf, bufix, from,
(unsigned char *)0, (unsigned)length);
/* If the IP or UDP checksum was bad, skip the packet... */
if (offset < 0)
......
......@@ -44,7 +44,7 @@
#ifndef lint
static char copyright[] =
"$Id: nit.c,v 1.30 2000/06/08 21:14:15 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: nit.c,v 1.31 2000/07/27 09:02:34 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
......@@ -299,11 +299,12 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct sockaddr_in *to;
struct hardware *hto;
{
unsigned bufp;
unsigned char buf [1536 + sizeof (struct sockaddr)];
unsigned hbufp, ibufp;
double hh [16];
double ih [1536 / sizeof (double)];
unsigned char *buf = (unsigned char *)ih;
struct sockaddr *junk;
struct strbuf ctl, data;
int hw_end;
struct sockaddr_in foo;
int result;
......@@ -312,34 +313,30 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
len, from, to, hto);
/* Start with the sockaddr struct... */
junk = (struct sockaddr *)&buf [0];
bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
junk = (struct sockaddr *)&hh [0];
hbufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
ibufp = 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);
assemble_hw_header (interface, (unsigned char *)junk, &hbufp, hto);
assemble_udp_ip_header (interface, buf, &ibufp,
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 */
junk -> sa_len = hbufp - 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;
ctl.buf = (char *)&hh [0];
ctl.maxlen = ctl.len = hbufp;
data.buf = (char *)&ih [0];
data.maxlen = data.len = ibufp + len;
result = putmsg (interface -> wfdesc, &ctl, &data, 0);
if (result < 0)
......
......@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: options.c,v 1.62 2000/06/28 23:35:22 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: options.c,v 1.63 2000/07/27 09:02:35 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
......@@ -205,7 +205,7 @@ int cons_options (inpacket, outpacket, lease, mms, in_options, cfg_options,
int mms;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
int overload; /* Overload flags that may be set. */
int terminate;
int bootpp;
......@@ -420,7 +420,7 @@ int store_options (buffer, buflen, packet, lease,
struct lease *lease;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
unsigned *priority_list;
int priority_len;
unsigned first_cutoff, second_cutoff;
......@@ -751,7 +751,7 @@ int hashed_option_get (result, universe, packet, lease,
struct option_state *in_options;
struct option_state *cfg_options;
struct option_state *options;
struct binding_scope *scope;
struct binding_scope **scope;
unsigned code;
{
struct option_cache *oc;
......@@ -776,7 +776,7 @@ int agent_option_get (result, universe, packet, lease,
struct option_state *in_options;
struct option_state *cfg_options;
struct option_state *options;
struct binding_scope *scope;
struct binding_scope **scope;
unsigned code;
{
struct agent_options *ao;
......@@ -1154,7 +1154,7 @@ int store_option (result, universe, packet, lease,
struct lease *lease;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;
struct option_cache *oc;
{
struct data_string d1, d2;
......@@ -1201,7 +1201,7 @@ int option_space_encapsulate (result, packet, lease,
struct lease *lease;
struct option_state *in_options;
struct option_state *cfg_options;
struct binding_scope *scope;
struct binding_scope **scope;