[klibc] PATCH: command line argument for ipconfig to require a dhcp option
Άλκης
Άλκης
Thu Oct 9 09:24:56 PDT 2008
Στις 08-10-2008, ημέρα Τετ, και ώρα 10:56 -0700, ο/η H. Peter Anvin
έγραψε:
> (1) is probably best simply by having precedence in dhclient.
I implemented this for a single dhcp option, I'm sending (I hope) the
git diff as an attachment.
When one doesn't use the new command line argument, he/she shouldn't be
observing *anything* different (no delays etc).
Kind regards,
Alkis Georgopoulos
-------------- next part --------------
commit 07e87cd45cf5e71c8709fad1c885507271d73b02
Author: Άλκης Γεωργόπουλος <alkisg at gmail.com>
Date: Thu Oct 9 19:10:51 2008 +0300
Signed-off-by: Alkis Georgopoulos <alkisg at gmail.com>
Patch to provide a command line argument for ipconfig to ignore offers that do not contain a specified DHCP option.
diff --git a/usr/kinit/ipconfig/README b/usr/kinit/ipconfig/README
index 5c8227a..0db4c65 100644
--- a/usr/kinit/ipconfig/README
+++ b/usr/kinit/ipconfig/README
@@ -3,8 +3,8 @@ BOOTP/DHCP client for klibc
Usage:
-ipconfig [-c proto] [-d interface] [-i identifier]
- [-n] [-p port] [-t timeout] [interface ...]
+ipconfig [-c proto] [-d interface] [-i identifier] [-n]
+ [-p port] [-t timeout] [-r option] [interface ...]
-c proto Use PROTO as the configuration protocol for all
interfaces, unless overridden by specific interfaces.
@@ -15,6 +15,8 @@ ipconfig [-c proto] [-d interface] [-i identifier]
be performed.
-p port Send bootp/dhcp broadcasts from PORT, to PORT - 1.
-t timeout Give up on all unconfigured interfaces after TIMEOUT secs.
+-r option Require that dhcp offers include a specific dhcp
+ OPTION (0-254) in order to get accepted.
You can configure multiple interfaces by passing multiple interface
specs on the command line, or by using the special interface name
diff --git a/usr/kinit/ipconfig/bootp_proto.c b/usr/kinit/ipconfig/bootp_proto.c
index 236bde9..b138e0f 100644
--- a/usr/kinit/ipconfig/bootp_proto.c
+++ b/usr/kinit/ipconfig/bootp_proto.c
@@ -61,6 +61,9 @@ int bootp_send_request(struct netdev *dev)
int bootp_parse(struct netdev *dev, struct bootp_hdr *hdr,
uint8_t *exts, int extlen)
{
+ int got_required_option = 0;
+ uint8_t type = 0;
+
dev->bootp.gateway = hdr->giaddr;
dev->ip_addr = hdr->yiaddr;
dev->ip_server = hdr->siaddr;
@@ -82,6 +85,9 @@ int bootp_parse(struct netdev *dev, struct bootp_hdr *hdr,
int len;
uint8_t opt = *ext++;
+ if (opt == required_option)
+ got_required_option = 1;
+
if (opt == 0)
continue;
else if (opt == 255)
@@ -135,10 +141,19 @@ int bootp_parse(struct netdev *dev, struct bootp_hdr *hdr,
memcpy(&dev->nisdomainname, ext, len);
dev->nisdomainname[len] = '\0';
break;
+ case 53: /* DHCP message type */
+ type = *ext;
+ break;
case 54: /* server identifier */
if (len == 4 && !dev->ip_server)
memcpy(&dev->ip_server, ext, 4);
break;
+ case 67: /* bootfile name, when option overload is set */
+ if (len > sizeof(dev->filename) - 1)
+ len = sizeof(dev->filename) - 1;
+ memcpy(&dev->filename, ext, len);
+ dev->filename[len] = '\0';
+ break;
}
ext += len;
@@ -146,9 +161,23 @@ int bootp_parse(struct netdev *dev, struct bootp_hdr *hdr,
}
/*
- * Got packet.
+ * If we got a DHCP_OFFER message type, and the required_option was not
+ * set, return 0 (=the message is to be ignored), else return 1.
*/
- return 1;
+ if (type == 2) {
+ /*
+ * Check for the equivalent of some required_options inside the header.
+ * Options sname=66 and file=67 may be either in the header, or, when
+ * option overload is set, in the variable options field.
+ */
+ if ((required_option == 66 && hdr->server_name[0] != '\0') ||
+ (required_option == 67 && hdr->boot_file[0] != '\0'))
+ got_required_option = 1;
+
+ return got_required_option;
+ }
+ else
+ return 1;
}
/*
diff --git a/usr/kinit/ipconfig/ipconfig.h b/usr/kinit/ipconfig/ipconfig.h
index 6d776e0..32b5183 100644
--- a/usr/kinit/ipconfig/ipconfig.h
+++ b/usr/kinit/ipconfig/ipconfig.h
@@ -10,6 +10,8 @@
extern uint16_t cfg_local_port;
extern uint16_t cfg_remote_port;
+extern int required_option;
+
extern char vendor_class_identifier[];
extern int vendor_class_identifier_len;
diff --git a/usr/kinit/ipconfig/main.c b/usr/kinit/ipconfig/main.c
index 2ded0f3..e7d7c03 100644
--- a/usr/kinit/ipconfig/main.c
+++ b/usr/kinit/ipconfig/main.c
@@ -31,6 +31,9 @@ static int loop_timeout = -1;
static int configured;
static int bringup_first = 0;
+/* Require this DHCP option. Defaults to 255 = End Option, always present. */
+int required_option = 255;
+
/* DHCP vendor class identifier */
char vendor_class_identifier[260];
int vendor_class_identifier_len;
@@ -723,7 +726,7 @@ int ipconfig_main(int argc, char *argv[])
set_vendor_identifier("Linux ipconfig");
do {
- c = getopt(argc, argv, "c:d:i:onp:t:");
+ c = getopt(argc, argv, "c:d:i:onp:t:r:");
if (c == EOF)
break;
@@ -751,6 +754,15 @@ int ipconfig_main(int argc, char *argv[])
longjmp(abort_buf, 1);
}
break;
+ case 'r':
+ required_option = atoi(optarg);
+ if (required_option < 0 || required_option > 254) {
+ fprintf(stderr,
+ "%s: invalid required option %d\n",
+ progname, required_option);
+ longjmp(abort_buf, 1);
+ }
+ break;
case 'i':
set_vendor_identifier(optarg);
break;
More information about the klibc
mailing list