|
@@ -28,6 +28,9 @@
|
|
*
|
|
*
|
|
* Multiple Nameservers in /proc/net/pnp
|
|
* Multiple Nameservers in /proc/net/pnp
|
|
* -- Josef Siemes <jsiemes@web.de>, Aug 2002
|
|
* -- Josef Siemes <jsiemes@web.de>, Aug 2002
|
|
|
|
+ *
|
|
|
|
+ * NTP servers in /proc/net/ipconfig/ntp_servers
|
|
|
|
+ * -- Chris Novakovic <chris@chrisn.me.uk>, April 2018
|
|
*/
|
|
*/
|
|
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/types.h>
|
|
@@ -93,6 +96,7 @@
|
|
#define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */
|
|
#define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */
|
|
#define CONF_NAMESERVERS_MAX 3 /* Maximum number of nameservers
|
|
#define CONF_NAMESERVERS_MAX 3 /* Maximum number of nameservers
|
|
- '3' from resolv.h */
|
|
- '3' from resolv.h */
|
|
|
|
+#define CONF_NTP_SERVERS_MAX 3 /* Maximum number of NTP servers */
|
|
|
|
|
|
#define NONE cpu_to_be32(INADDR_NONE)
|
|
#define NONE cpu_to_be32(INADDR_NONE)
|
|
#define ANY cpu_to_be32(INADDR_ANY)
|
|
#define ANY cpu_to_be32(INADDR_ANY)
|
|
@@ -152,12 +156,16 @@ static int ic_proto_used; /* Protocol used, if any */
|
|
#define ic_proto_used 0
|
|
#define ic_proto_used 0
|
|
#endif
|
|
#endif
|
|
static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
|
|
static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
|
|
|
|
+static __be32 ic_ntp_servers[CONF_NTP_SERVERS_MAX]; /* NTP server IP addresses */
|
|
static u8 ic_domain[64]; /* DNS (not NIS) domain name */
|
|
static u8 ic_domain[64]; /* DNS (not NIS) domain name */
|
|
|
|
|
|
/*
|
|
/*
|
|
* Private state.
|
|
* Private state.
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+/* proc_dir_entry for /proc/net/ipconfig */
|
|
|
|
+static struct proc_dir_entry *ipconfig_dir;
|
|
|
|
+
|
|
/* Name of user-selected boot device */
|
|
/* Name of user-selected boot device */
|
|
static char user_dev_name[IFNAMSIZ] __initdata = { 0, };
|
|
static char user_dev_name[IFNAMSIZ] __initdata = { 0, };
|
|
|
|
|
|
@@ -576,6 +584,15 @@ static inline void __init ic_nameservers_predef(void)
|
|
ic_nameservers[i] = NONE;
|
|
ic_nameservers[i] = NONE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Predefine NTP servers */
|
|
|
|
+static inline void __init ic_ntp_servers_predef(void)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < CONF_NTP_SERVERS_MAX; i++)
|
|
|
|
+ ic_ntp_servers[i] = NONE;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* DHCP/BOOTP support.
|
|
* DHCP/BOOTP support.
|
|
*/
|
|
*/
|
|
@@ -671,6 +688,7 @@ ic_dhcp_init_options(u8 *options, struct ic_device *d)
|
|
17, /* Boot path */
|
|
17, /* Boot path */
|
|
26, /* MTU */
|
|
26, /* MTU */
|
|
40, /* NIS domain name */
|
|
40, /* NIS domain name */
|
|
|
|
+ 42, /* NTP servers */
|
|
};
|
|
};
|
|
|
|
|
|
*e++ = 55; /* Parameter request list */
|
|
*e++ = 55; /* Parameter request list */
|
|
@@ -721,9 +739,11 @@ static void __init ic_bootp_init_ext(u8 *e)
|
|
*e++ = 3; /* Default gateway request */
|
|
*e++ = 3; /* Default gateway request */
|
|
*e++ = 4;
|
|
*e++ = 4;
|
|
e += 4;
|
|
e += 4;
|
|
- *e++ = 5; /* Name server request */
|
|
|
|
- *e++ = 8;
|
|
|
|
- e += 8;
|
|
|
|
|
|
+#if CONF_NAMESERVERS_MAX > 0
|
|
|
|
+ *e++ = 6; /* (DNS) name server request */
|
|
|
|
+ *e++ = 4 * CONF_NAMESERVERS_MAX;
|
|
|
|
+ e += 4 * CONF_NAMESERVERS_MAX;
|
|
|
|
+#endif
|
|
*e++ = 12; /* Host name request */
|
|
*e++ = 12; /* Host name request */
|
|
*e++ = 32;
|
|
*e++ = 32;
|
|
e += 32;
|
|
e += 32;
|
|
@@ -748,7 +768,13 @@ static void __init ic_bootp_init_ext(u8 *e)
|
|
*/
|
|
*/
|
|
static inline void __init ic_bootp_init(void)
|
|
static inline void __init ic_bootp_init(void)
|
|
{
|
|
{
|
|
|
|
+ /* Re-initialise all name servers and NTP servers to NONE, in case any
|
|
|
|
+ * were set via the "ip=" or "nfsaddrs=" kernel command line parameters:
|
|
|
|
+ * any IP addresses specified there will already have been decoded but
|
|
|
|
+ * are no longer needed
|
|
|
|
+ */
|
|
ic_nameservers_predef();
|
|
ic_nameservers_predef();
|
|
|
|
+ ic_ntp_servers_predef();
|
|
|
|
|
|
dev_add_pack(&bootp_packet_type);
|
|
dev_add_pack(&bootp_packet_type);
|
|
}
|
|
}
|
|
@@ -912,6 +938,15 @@ static void __init ic_do_bootp_ext(u8 *ext)
|
|
ic_bootp_string(utsname()->domainname, ext+1, *ext,
|
|
ic_bootp_string(utsname()->domainname, ext+1, *ext,
|
|
__NEW_UTS_LEN);
|
|
__NEW_UTS_LEN);
|
|
break;
|
|
break;
|
|
|
|
+ case 42: /* NTP servers */
|
|
|
|
+ servers = *ext / 4;
|
|
|
|
+ if (servers > CONF_NTP_SERVERS_MAX)
|
|
|
|
+ servers = CONF_NTP_SERVERS_MAX;
|
|
|
|
+ for (i = 0; i < servers; i++) {
|
|
|
|
+ if (ic_ntp_servers[i] == NONE)
|
|
|
|
+ memcpy(&ic_ntp_servers[i], ext+1+4*i, 4);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1258,6 +1293,7 @@ static int __init ic_dynamic(void)
|
|
|
|
|
|
#ifdef CONFIG_PROC_FS
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
|
|
|
|
+/* Name servers: */
|
|
static int pnp_seq_show(struct seq_file *seq, void *v)
|
|
static int pnp_seq_show(struct seq_file *seq, void *v)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
@@ -1294,6 +1330,62 @@ static const struct file_operations pnp_seq_fops = {
|
|
.llseek = seq_lseek,
|
|
.llseek = seq_lseek,
|
|
.release = single_release,
|
|
.release = single_release,
|
|
};
|
|
};
|
|
|
|
+
|
|
|
|
+/* Create the /proc/net/ipconfig directory */
|
|
|
|
+static int __init ipconfig_proc_net_init(void)
|
|
|
|
+{
|
|
|
|
+ ipconfig_dir = proc_net_mkdir(&init_net, "ipconfig", init_net.proc_net);
|
|
|
|
+ if (!ipconfig_dir)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Create a new file under /proc/net/ipconfig */
|
|
|
|
+static int ipconfig_proc_net_create(const char *name,
|
|
|
|
+ const struct file_operations *fops)
|
|
|
|
+{
|
|
|
|
+ char *pname;
|
|
|
|
+ struct proc_dir_entry *p;
|
|
|
|
+
|
|
|
|
+ if (!ipconfig_dir)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ pname = kasprintf(GFP_KERNEL, "%s%s", "ipconfig/", name);
|
|
|
|
+ if (!pname)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ p = proc_create(pname, 0444, init_net.proc_net, fops);
|
|
|
|
+ kfree(pname);
|
|
|
|
+ if (!p)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Write NTP server IP addresses to /proc/net/ipconfig/ntp_servers */
|
|
|
|
+static int ntp_servers_seq_show(struct seq_file *seq, void *v)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < CONF_NTP_SERVERS_MAX; i++) {
|
|
|
|
+ if (ic_ntp_servers[i] != NONE)
|
|
|
|
+ seq_printf(seq, "%pI4\n", &ic_ntp_servers[i]);
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int ntp_servers_seq_open(struct inode *inode, struct file *file)
|
|
|
|
+{
|
|
|
|
+ return single_open(file, ntp_servers_seq_show, NULL);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static const struct file_operations ntp_servers_seq_fops = {
|
|
|
|
+ .open = ntp_servers_seq_open,
|
|
|
|
+ .read = seq_read,
|
|
|
|
+ .llseek = seq_lseek,
|
|
|
|
+ .release = single_release,
|
|
|
|
+};
|
|
#endif /* CONFIG_PROC_FS */
|
|
#endif /* CONFIG_PROC_FS */
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1368,8 +1460,20 @@ static int __init ip_auto_config(void)
|
|
int err;
|
|
int err;
|
|
unsigned int i;
|
|
unsigned int i;
|
|
|
|
|
|
|
|
+ /* Initialise all name servers and NTP servers to NONE (but only if the
|
|
|
|
+ * "ip=" or "nfsaddrs=" kernel command line parameters weren't decoded,
|
|
|
|
+ * otherwise we'll overwrite the IP addresses specified there)
|
|
|
|
+ */
|
|
|
|
+ if (ic_set_manually == 0) {
|
|
|
|
+ ic_nameservers_predef();
|
|
|
|
+ ic_ntp_servers_predef();
|
|
|
|
+ }
|
|
|
|
+
|
|
#ifdef CONFIG_PROC_FS
|
|
#ifdef CONFIG_PROC_FS
|
|
proc_create("pnp", 0444, init_net.proc_net, &pnp_seq_fops);
|
|
proc_create("pnp", 0444, init_net.proc_net, &pnp_seq_fops);
|
|
|
|
+
|
|
|
|
+ if (ipconfig_proc_net_init() == 0)
|
|
|
|
+ ipconfig_proc_net_create("ntp_servers", &ntp_servers_seq_fops);
|
|
#endif /* CONFIG_PROC_FS */
|
|
#endif /* CONFIG_PROC_FS */
|
|
|
|
|
|
if (!ic_enable)
|
|
if (!ic_enable)
|
|
@@ -1481,16 +1585,32 @@ static int __init ip_auto_config(void)
|
|
&ic_servaddr, &root_server_addr, root_server_path);
|
|
&ic_servaddr, &root_server_addr, root_server_path);
|
|
if (ic_dev_mtu)
|
|
if (ic_dev_mtu)
|
|
pr_cont(", mtu=%d", ic_dev_mtu);
|
|
pr_cont(", mtu=%d", ic_dev_mtu);
|
|
- for (i = 0; i < CONF_NAMESERVERS_MAX; i++)
|
|
|
|
|
|
+ /* Name servers (if any): */
|
|
|
|
+ for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
|
|
if (ic_nameservers[i] != NONE) {
|
|
if (ic_nameservers[i] != NONE) {
|
|
- pr_cont(" nameserver%u=%pI4",
|
|
|
|
- i, &ic_nameservers[i]);
|
|
|
|
- break;
|
|
|
|
|
|
+ if (i == 0)
|
|
|
|
+ pr_info(" nameserver%u=%pI4",
|
|
|
|
+ i, &ic_nameservers[i]);
|
|
|
|
+ else
|
|
|
|
+ pr_cont(", nameserver%u=%pI4",
|
|
|
|
+ i, &ic_nameservers[i]);
|
|
}
|
|
}
|
|
- for (i++; i < CONF_NAMESERVERS_MAX; i++)
|
|
|
|
- if (ic_nameservers[i] != NONE)
|
|
|
|
- pr_cont(", nameserver%u=%pI4", i, &ic_nameservers[i]);
|
|
|
|
- pr_cont("\n");
|
|
|
|
|
|
+ if (i + 1 == CONF_NAMESERVERS_MAX)
|
|
|
|
+ pr_cont("\n");
|
|
|
|
+ }
|
|
|
|
+ /* NTP servers (if any): */
|
|
|
|
+ for (i = 0; i < CONF_NTP_SERVERS_MAX; i++) {
|
|
|
|
+ if (ic_ntp_servers[i] != NONE) {
|
|
|
|
+ if (i == 0)
|
|
|
|
+ pr_info(" ntpserver%u=%pI4",
|
|
|
|
+ i, &ic_ntp_servers[i]);
|
|
|
|
+ else
|
|
|
|
+ pr_cont(", ntpserver%u=%pI4",
|
|
|
|
+ i, &ic_ntp_servers[i]);
|
|
|
|
+ }
|
|
|
|
+ if (i + 1 == CONF_NTP_SERVERS_MAX)
|
|
|
|
+ pr_cont("\n");
|
|
|
|
+ }
|
|
#endif /* !SILENT */
|
|
#endif /* !SILENT */
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1588,7 +1708,9 @@ static int __init ip_auto_config_setup(char *addrs)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* Initialise all name servers and NTP servers to NONE */
|
|
ic_nameservers_predef();
|
|
ic_nameservers_predef();
|
|
|
|
+ ic_ntp_servers_predef();
|
|
|
|
|
|
/* Parse string for static IP assignment. */
|
|
/* Parse string for static IP assignment. */
|
|
ip = addrs;
|
|
ip = addrs;
|
|
@@ -1647,6 +1769,13 @@ static int __init ip_auto_config_setup(char *addrs)
|
|
ic_nameservers[1] = NONE;
|
|
ic_nameservers[1] = NONE;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+ case 9:
|
|
|
|
+ if (CONF_NTP_SERVERS_MAX >= 1) {
|
|
|
|
+ ic_ntp_servers[0] = in_aton(ip);
|
|
|
|
+ if (ic_ntp_servers[0] == ANY)
|
|
|
|
+ ic_ntp_servers[0] = NONE;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ip = cp;
|
|
ip = cp;
|