summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Benoit <benno@cvs.openbsd.org>2021-08-04 18:17:24 +0000
committerSebastian Benoit <benno@cvs.openbsd.org>2021-08-04 18:17:24 +0000
commit95c8df6da51be39f18c77358db9b653e24ef6157 (patch)
tree0cd7cc1634433f2ff64510e554437ebcbe2ce23c
parent112d58ac59fe78a768c25013979b5707d97ee82f (diff)
Add a new 'nameserver' command to route(8).
It sends nameserver proposals to resolvd(8) using the dns proposal protocol over the route socket. Based on a seperate program written by florian@. deraadt noticed some whitespace issues. more fixes and ok florian@
-rw-r--r--sbin/route/keywords.h5
-rw-r--r--sbin/route/keywords.sh3
-rw-r--r--sbin/route/route.827
-rw-r--r--sbin/route/route.c146
4 files changed, 174 insertions, 7 deletions
diff --git a/sbin/route/keywords.h b/sbin/route/keywords.h
index 0fd50932596..eb2901f9e21 100644
--- a/sbin/route/keywords.h
+++ b/sbin/route/keywords.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: keywords.h,v 1.35 2020/10/29 21:15:26 denis Exp $ */
+/* $OpenBSD: keywords.h,v 1.36 2021/08/04 18:17:23 benno Exp $ */
/* WARNING! This file was generated by keywords.sh */
@@ -45,6 +45,7 @@ enum {
K_MPLS,
K_MPLSLABEL,
K_MTU,
+ K_NAMESERVER,
K_NET,
K_NETMASK,
K_NOBFD,
@@ -109,6 +110,7 @@ struct keytab keywords[] = {
{ "mpls", K_MPLS },
{ "mplslabel", K_MPLSLABEL },
{ "mtu", K_MTU },
+ { "nameserver", K_NAMESERVER },
{ "net", K_NET },
{ "netmask", K_NETMASK },
{ "nobfd", K_NOBFD },
@@ -135,4 +137,3 @@ struct keytab keywords[] = {
{ "static", K_STATIC },
{ "swap", K_SWAP },
};
-
diff --git a/sbin/route/keywords.sh b/sbin/route/keywords.sh
index 369f1b08aaa..6f9f5a21e4d 100644
--- a/sbin/route/keywords.sh
+++ b/sbin/route/keywords.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $OpenBSD: keywords.sh,v 1.33 2020/10/29 21:15:26 denis Exp $
+# $OpenBSD: keywords.sh,v 1.34 2021/08/04 18:17:23 benno Exp $
# $NetBSD: keywords.sh,v 1.2 1996/11/15 18:57:21 gwr Exp $
# @(#)keywords 8.2 (Berkeley) 3/19/94
#
@@ -46,6 +46,7 @@ mpath
mpls
mplslabel
mtu
+nameserver
net
netmask
nobfd
diff --git a/sbin/route/route.8 b/sbin/route/route.8
index 83e48ec883d..3624e4eaf18 100644
--- a/sbin/route/route.8
+++ b/sbin/route/route.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: route.8,v 1.95 2021/01/02 15:35:24 schwarze Exp $
+.\" $OpenBSD: route.8,v 1.96 2021/08/04 18:17:23 benno Exp $
.\" $NetBSD: route.8,v 1.6 1995/03/18 15:00:13 cgd Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)route.8 8.3 (Berkeley) 3/19/94
.\"
-.Dd $Mdocdate: January 2 2021 $
+.Dd $Mdocdate: August 4 2021 $
.Dt ROUTE 8
.Os
.Sh NAME
@@ -215,7 +215,6 @@ priority are shown.
.Fl ifp
.Ar interface
.Xc
-.Pp
Set the preferred source address.
If
.Ar address
@@ -237,6 +236,26 @@ destination is on-link
source address is assigned to a disabled interface
.El
.El
+.Bl -tag -width Fl -compact
+.It Xo
+.Ic route
+.Op Fl dtv
+.Op Fl T Ar rtable
+.Tg
+.Cm nameserver
+.Op Ar address
+.Op Ar ...
+.Xc
+Send a list of up to five nameserver addresses proposals to
+.Xr resolvd 8 .
+.Xr resolvd 8
+will react upon this request by writing the nameservers to
+.Pa /etc/resolv.conf .
+If no
+.Ar address
+argument is given, a request to remove the nameservers previously entered for
+the given interface is sent.
+.El
.Pp
.Tg destination
.Tg gateway
@@ -603,9 +622,11 @@ to create the new entry.
.Xr route 4 ,
.Xr tcp 4 ,
.Xr hosts 5 ,
+.Xr resolv.conf 5 ,
.Xr mygate 5 ,
.Xr bgpd 8 ,
.Xr ospfd 8 ,
+.Xr resolvd 8 ,
.Xr ripd 8 ,
.Xr sysctl 8
.Sh HISTORY
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 8af7c93dc9e..376fb37f74d 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.255 2021/06/26 15:42:58 deraadt Exp $ */
+/* $OpenBSD: route.c,v 1.256 2021/08/04 18:17:23 benno Exp $ */
/* $NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $ */
/*
@@ -93,6 +93,7 @@ int show(int, char *[]);
int keycmp(const void *, const void *);
int keyword(char *);
void monitor(int, char *[]);
+int nameserver(int, char **);
int prefixlen(int, char *);
void sockaddr(char *, struct sockaddr *);
void sodump(sup, char *);
@@ -282,6 +283,9 @@ main(int argc, char **argv)
case K_MONITOR:
monitor(argc, argv);
break;
+ case K_NAMESERVER:
+ rval = nameserver(argc, argv);
+ break;
default:
usage(*argv);
/* NOTREACHED */
@@ -1129,6 +1133,146 @@ monitor(int argc, char *argv[])
}
}
+
+int
+nameserver(int argc, char *argv[])
+{
+ struct rt_msghdr rtm;
+ struct sockaddr_rtdns rtdns;
+ struct iovec iov[3];
+ struct addrinfo hints, *res;
+ struct in_addr ns4[5];
+ struct in6_addr ns6[5];
+ size_t ns4_count = 0, ns6_count = 0;
+ long pad = 0;
+ unsigned int if_index;
+ int error = 0, iovcnt = 0, padlen, i;
+ char *if_name, buf[INET6_ADDRSTRLEN];
+
+
+ argc--;
+ argv++;
+ if (argc == 0)
+ usage(NULL);
+
+ if_name = *argv;
+ argc--;
+ argv++;
+
+ if ((if_index = if_nametoindex(if_name)) == 0)
+ errx(1, "unknown interface: %s", if_name);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+
+#ifndef nitems
+#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
+#endif
+
+ for (; argc > 0; argc--, argv++) {
+ error = getaddrinfo(*argv, NULL, &hints, &res);
+ if (error) {
+ errx(1, "%s", gai_strerror(error));
+ }
+ if (res == NULL) {
+ errx(1, "%s: unknown", *argv);
+ }
+
+ switch (res->ai_addr->sa_family) {
+ case AF_INET:
+ if (ns4_count >= nitems(ns4)) {
+ warnx("ignoring superflous nameserver: %s",
+ *argv);
+ break;
+ }
+ memcpy(&ns4[ns4_count++],
+ &((struct sockaddr_in *)res->ai_addr)->sin_addr,
+ sizeof(struct in_addr));
+ break;
+ case AF_INET6:
+ if (ns6_count >= nitems(ns6)) {
+ warnx("ignoring superflous nameserver: %s",
+ *argv);
+ break;
+ }
+ memcpy(&ns6[ns6_count++],
+ &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
+ sizeof(struct in6_addr));
+ break;
+ default:
+ errx(1, "unknown address family");
+ }
+ freeaddrinfo(res);
+ }
+
+ if (argc > 0)
+ warnx("ignoring additional nameservers");
+
+ if (verbose) {
+ for (i = 0; i < ns4_count; i++)
+ warnx("v4: %s", inet_ntop(AF_INET, &ns4[i], buf,
+ sizeof(buf)));
+ for (i = 0; i < ns6_count; i++)
+ warnx("v6: %s", inet_ntop(AF_INET6, &ns6[i], buf,
+ sizeof(buf)));
+ }
+
+ memset(&rtm, 0, sizeof(rtm));
+
+ rtm.rtm_version = RTM_VERSION;
+ rtm.rtm_type = RTM_PROPOSAL;
+ rtm.rtm_msglen = sizeof(rtm);
+ rtm.rtm_tableid = tableid;
+ rtm.rtm_index = if_index;
+ rtm.rtm_seq = 1;
+ rtm.rtm_priority = RTP_PROPOSAL_STATIC;
+ rtm.rtm_addrs = RTA_DNS;
+ rtm.rtm_flags = RTF_UP;
+
+ iov[iovcnt].iov_base = &rtm;
+ iov[iovcnt++].iov_len = sizeof(rtm);
+
+ iov[iovcnt].iov_base = &rtdns;
+ iov[iovcnt++].iov_len = sizeof(rtdns);
+ rtm.rtm_msglen += sizeof(rtdns);
+
+ padlen = ROUNDUP(sizeof(rtdns)) - sizeof(rtdns);
+ if (padlen > 0) {
+ iov[iovcnt].iov_base = &pad;
+ iov[iovcnt++].iov_len = padlen;
+ rtm.rtm_msglen += padlen;
+ }
+
+ memset(&rtdns, 0, sizeof(rtdns));
+ rtdns.sr_family = AF_INET;
+ rtdns.sr_len = 2 + ns4_count * sizeof(struct in_addr);
+ memcpy(rtdns.sr_dns, ns4, rtdns.sr_len - 2);
+
+ if (debugonly)
+ return (0);
+
+ if (writev(s, iov, iovcnt) == -1) {
+ warn("failed to send route message");
+ error = 1;
+ }
+
+ rtm.rtm_seq++;
+
+ memset(&rtdns, 0, sizeof(rtdns));
+ rtdns.sr_family = AF_INET6;
+ rtdns.sr_len = 2 + ns6_count * sizeof(struct in6_addr);
+ memcpy(rtdns.sr_dns, ns6, rtdns.sr_len - 2);
+
+ if (writev(s, iov, iovcnt) == -1) {
+ warn("failed to send route message");
+ error = 1;
+ }
+
+ return (error);
+}
+
struct {
struct rt_msghdr m_rtm;
char m_space[512];