bin/89988: [PATCH] bootparamd null host support and whoami fix
John
omen-pub at omenlabs.com
Mon Dec 5 19:20:06 GMT 2005
>Number: 89988
>Category: bin
>Synopsis: [PATCH] bootparamd null host support and whoami fix
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Dec 05 19:20:02 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: John
>Release: 6.0 Release i386
>Organization:
>Environment:
FreeBSD scale 6.0-RELEASE FreeBSD 6.0-RELEASE #0: Thu Nov 3 09:36:13 UTC 2005 root at x64.samsco.home:/usr/obj/usr/src/sys/GENERIC i386
>Description:
There are two issues with bootparamd that I ran into trying to
get Solaris Jumpstart working nicely. One was permitting null
hostnames. Certain options are passed to the jumpstart client
using /etc/bootparams file entries like "term=:vt100". The current
implementation only makes an exception for the file "dump=..." and
will not return anything else if it can not be resolved. I have
added in a check to return an address of 0.0.0.0 if the length of
the hostname is zero.
The second issue is a little more significant. If a router
address is not supplied using the -r option, bootparamd uses the
function get_myaddress(3) to determine the address of the host.
The bootparamd(8) man page states:
-r router The default router (a machine or an IP-address). This
defaults to the machine running the server.
The function get_myaddress always returns INADDR_LOOPBACK. This
qualify as a bug. Using -r solves this problem, unless you are
running on multiple networks. The patch attempts to make rpc.bootparamd
more intelligent. If -r is not supplied, the ip address of the
client is checked against all configured network interfaces on the
host in the function myaddr. If the client is on a local subnet,
the ip address of the server on that network is returned (if not,
INADDR_LOOPBACK). This allows for whoami on multiple networks.
>How-To-Repeat:
>Fix:
diff -urN bootparamd.orig/bootparamd.c bootparamd/bootparamd.c
--- bootparamd.orig/bootparamd.c Thu Dec 1 16:06:21 2005
+++ bootparamd/bootparamd.c Thu Dec 1 16:10:13 2005
@@ -27,7 +27,9 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
-extern int debug, dolog;
+#include <netinet/in.h>
+#include <ifaddrs.h>
+extern int debug, dolog, route_set;
extern unsigned long route_addr;
extern char *bootpfile;
@@ -42,6 +44,7 @@
int getthefile __P((char *, char *, char *, int));
int checkhost __P((char *, char *, int));
+unsigned long myaddr __P((unsigned long));
bp_whoami_res *
bootparamproc_whoami_1_svc(whoami, req)
@@ -79,10 +82,15 @@
getdomainname(domain_name, MAX_MACHINE_NAME);
res.domain_name = domain_name;
- if ( res.router_address.address_type != IP_ADDR_TYPE ) {
+ if (!route_set) {
+ route_addr = myaddr(haddr);
+ }
+
+ if ( (res.router_address.address_type != IP_ADDR_TYPE) && route_set ) {
res.router_address.address_type = IP_ADDR_TYPE;
bcopy( &route_addr, &res.router_address.bp_address_u.ip_addr, 4);
}
+
if (debug) fprintf(stderr,
"Returning %s %s %d.%d.%d.%d\n",
res.client_name,
@@ -139,8 +147,16 @@
hostname[where - buffer] = '\0';
where++;
strcpy(path, where);
- he = gethostbyname(hostname);
- if ( !he ) goto failed;
+
+ /* support null hostnames which are useful for solaris jumpstart */
+ if (strlen(hostname)==0) {
+ bzero(&res.server_address.bp_address_u.ip_addr,4);
+ }
+ else {
+ he = gethostbyname(hostname);
+ if ( !he ) goto failed;
+ }
+
bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4);
res.server_name = hostname;
res.server_path = path;
@@ -355,4 +371,37 @@
}
if (fclose(bpf)) { warnx("could not close %s", bootpfile); }
return(res);
+}
+
+/* Check the client address against the networks we are
+listening on to have a more intelligent version of
+get_myaddress(), which always returns localhost */
+
+unsigned long
+myaddr(unsigned long clientip) {
+ struct ifaddrs *ifap, *ifaorig;
+ int i;
+ char* ifname = NULL;
+ unsigned long ifip, netmask;
+
+ getifaddrs(&ifaorig);
+ ifap = ifaorig;
+
+ while(ifap != NULL) {
+ if(ifap->ifa_addr->sa_family == AF_INET) {
+ bcopy(&ifap->ifa_addr->sa_data[2], &ifip, 4);
+ bcopy(&ifap->ifa_netmask->sa_data[2], &netmask, 4);
+
+ if((ifip & netmask) == (clientip & netmask))
+ goto done;
+ }
+
+ ifap = ifap->ifa_next;
+ }
+
+ ifip = INADDR_LOOPBACK;
+
+ done:
+ freeifaddrs(ifaorig);
+ return ifip;
}
diff -urN bootparamd.orig/main.c bootparamd/main.c
--- bootparamd.orig/main.c Thu Dec 1 16:06:21 2005
+++ bootparamd/main.c Thu Dec 1 15:50:56 2005
@@ -9,7 +9,7 @@
#ifndef lint
static const char rcsid[] =
- "$FreeBSD: /repoman/r/ncvs/src/usr.sbin/bootparamd/bootparamd/main.c,v 1.10 2004/06/08 12:11:19 stefanf Exp $";
+ "$FreeBSD: src/usr.sbin/bootparamd/bootparamd/main.c,v 1.10 2004/06/08 12:11:19 stefanf Exp $";
#endif /* not lint */
#include <ctype.h>
@@ -32,6 +32,7 @@
int debug = 0;
int dolog = 0;
+int route_set = 0;
unsigned long route_addr = -1;
struct sockaddr_in my_addr;
char *bootpfile = "/etc/bootparams";
@@ -55,6 +56,7 @@
debug = 1;
break;
case 'r':
+ route_set = 1;
if (isdigit((unsigned char)*optarg)) {
route_addr = inet_addr(optarg);
break;
@@ -85,11 +87,6 @@
if ( stat(bootpfile, &buf ) )
err(1, "%s", bootpfile);
-
- if (route_addr == -1) {
- get_myaddress(&my_addr);
- bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof (route_addr));
- }
if (!debug) {
if (daemon(0,0))
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list