diff options
Diffstat (limited to 'usr.sbin/dhcp/common')
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, <, 1); - note ("Released lease for IP address %s", - piaddr (lease -> ip_addr)); + if (lt.ends > cur_time) { + lt.ends = cur_time; + supersede_lease (lease, <, 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 *)𝔦 - 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, ¶m) < 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 |