Import NetBSD route(8)

Change-Id: I724a2a56157ea72afdd3f6a82239687894c8e3e8
This commit is contained in:
David van Moolenbroek 2017-02-15 12:08:12 +00:00
parent 90b801219a
commit 483e595557
17 changed files with 3783 additions and 1 deletions

View File

@ -225,6 +225,7 @@
./sbin/printconfig minix-base
./sbin/rcorder minix-base
./sbin/reboot minix-base
./sbin/route minix-base
./sbin/shutdown minix-base
./sbin/sysctl minix-base
./service minix-base

View File

@ -175,6 +175,7 @@
./usr/libdata/debug/sbin/printconfig.debug minix-debug debug
./usr/libdata/debug/sbin/rcorder.debug minix-debug debug
./usr/libdata/debug/sbin/reboot.debug minix-debug debug
./usr/libdata/debug/sbin/route.debug minix-debug debug
./usr/libdata/debug/sbin/shutdown.debug minix-debug debug
./usr/libdata/debug/sbin/sysctl.debug minix-debug debug
./usr/libdata/debug/service minix-debug

View File

@ -3455,6 +3455,7 @@
./usr/man/man8/renice.8 minix-man
./usr/man/man8/repartition.8 minix-man
./usr/man/man8/rotate.8 minix-man
./usr/man/man8/route.8 minix-man
./usr/man/man8/rshd.8 minix-man
./usr/man/man8/screendump.8 minix-man
./usr/man/man8/serial-ip.8 minix-man obsolete

View File

@ -11,7 +11,7 @@ SUBDIR= \
fsck ifconfig init \
mknod nologin \
ping \
reboot rcorder \
reboot rcorder route \
shutdown sysctl \
# support for various file systems

30
sbin/route/Makefile Normal file
View File

@ -0,0 +1,30 @@
# $NetBSD: Makefile,v 1.29 2015/09/14 05:12:52 ozaki-r Exp $
# @(#)Makefile 8.1 (Berkeley) 6/5/93
.include <bsd.own.mk>
RUMPPRG=route
MAN= route.8
SRCS= route.c show.c keywords.c rtutil.c
.PATH: ${.CURDIR}/../../lib/libc/net
RUMPSRCS= getaddrinfo.c getifaddrs.c getnameinfo.c
RUMPSRCS+= if_indextoname.c if_nametoindex.c
.if (${MKRUMP} != "no")
CPPFLAGS+= -DRUMP_ACTION
.endif
.if (${USE_INET6} != "no")
CPPFLAGS+=-DINET6
.endif
# The Makefile over in ../../distrib/utils/x_route
# would like keywords.[ch] to always exist here, so
# they are now checked in as sources.
#
# CPPFLAGS+=-I.
# CLEANFILES+= keywords.c keywords.h
# keywords.c keywords.h : keywords.sh
# ${HOST_SH} keywords.sh
.include <bsd.prog.mk>

40
sbin/route/extern.h Normal file
View File

@ -0,0 +1,40 @@
/* $NetBSD: extern.h,v 1.15 2014/11/06 21:29:32 christos Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
struct sockaddr;
struct sockaddr_x25;
struct sockaddr_ns;
void parse_show_opts(int, char * const *, int *, int *, const char **, bool);
/* show.c */
void show(int, char * const *, int);
/* route.c */
extern int nflag, Sflag;
#define NOTDEFSTRING "0.0.0.0/xxx.xxx.xxx.xxx\0"
int keyword(const char *);
const char *ns_print(struct sockaddr_ns *);
void usage(const char *)__attribute__((__noreturn__));

65
sbin/route/keywords.c Normal file
View File

@ -0,0 +1,65 @@
/* $NetBSD: keywords.c,v 1.10 2013/03/01 18:25:17 joerg Exp $ */
/* WARNING! This file was generated by keywords.sh */
#include "keywords.h"
struct keytab keywords[] = {
{"add", K_ADD},
{"atalk", K_ATALK},
{"blackhole", K_BLACKHOLE},
{"change", K_CHANGE},
{"cloned", K_CLONED},
{"cloning", K_CLONING},
{"delete", K_DELETE},
{"dst", K_DST},
{"expire", K_EXPIRE},
{"flush", K_FLUSH},
{"gateway", K_GATEWAY},
{"genmask", K_GENMASK},
{"get", K_GET},
{"host", K_HOST},
{"hopcount", K_HOPCOUNT},
{"iface", K_IFACE},
{"interface", K_INTERFACE},
{"ifa", K_IFA},
{"ifp", K_IFP},
{"inet", K_INET},
{"inet6", K_INET6},
{"link", K_LINK},
{"llinfo", K_LLINFO},
{"lock", K_LOCK},
{"lockrest", K_LOCKREST},
{"mask", K_MASK},
{"monitor", K_MONITOR},
{"mtu", K_MTU},
{"net", K_NET},
{"netmask", K_NETMASK},
{"nostatic", K_NOSTATIC},
{"prefixlen", K_PREFIXLEN},
{"proto1", K_PROTO1},
{"proto2", K_PROTO2},
{"recvpipe", K_RECVPIPE},
{"reject", K_REJECT},
{"rtt", K_RTT},
{"rttvar", K_RTTVAR},
{"sa", K_SA},
{"sendpipe", K_SENDPIPE},
{"show", K_SHOW},
{"ssthresh", K_SSTHRESH},
{"static", K_STATIC},
{"x25", K_X25},
{"xns", K_XNS},
{"xresolve", K_XRESOLVE},
{"flushall", K_FLUSHALL},
{"nocloned", K_NOCLONED},
{"nocloning", K_NOCLONING},
{"noblackhole", K_NOBLACKHOLE},
{"noreject", K_NOREJECT},
{"mpls", K_MPLS},
{"tag", K_TAG},
{"proxy", K_PROXY},
{0, 0}
};

64
sbin/route/keywords.h Normal file
View File

@ -0,0 +1,64 @@
/* $NetBSD: keywords.h,v 1.13 2013/03/01 18:25:17 joerg Exp $ */
/* WARNING! This file was generated by keywords.sh */
extern struct keytab {
const char *kt_cp;
int kt_i;
} keywords[];
#define K_ADD 1
#define K_ATALK 2
#define K_BLACKHOLE 3
#define K_CHANGE 4
#define K_CLONED 5
#define K_CLONING 6
#define K_DELETE 7
#define K_DST 8
#define K_EXPIRE 9
#define K_FLUSH 10
#define K_GATEWAY 11
#define K_GENMASK 12
#define K_GET 13
#define K_HOST 14
#define K_HOPCOUNT 15
#define K_IFACE 16
#define K_INTERFACE 17
#define K_IFA 18
#define K_IFP 19
#define K_INET 20
#define K_INET6 21
#define K_LINK 22
#define K_LLINFO 23
#define K_LOCK 24
#define K_LOCKREST 25
#define K_MASK 26
#define K_MONITOR 27
#define K_MTU 28
#define K_NET 29
#define K_NETMASK 30
#define K_NOSTATIC 31
#define K_PREFIXLEN 32
#define K_PROTO1 33
#define K_PROTO2 34
#define K_RECVPIPE 35
#define K_REJECT 36
#define K_RTT 37
#define K_RTTVAR 38
#define K_SA 39
#define K_SENDPIPE 40
#define K_SHOW 41
#define K_SSTHRESH 42
#define K_STATIC 43
#define K_X25 44
#define K_XNS 45
#define K_XRESOLVE 46
#define K_FLUSHALL 47
#define K_NOCLONED 48
#define K_NOCLONING 49
#define K_NOBLACKHOLE 50
#define K_NOREJECT 51
#define K_MPLS 52
#define K_TAG 53
#define K_PROXY 54

128
sbin/route/keywords.sh Executable file
View File

@ -0,0 +1,128 @@
#!/bin/sh
# $NetBSD: keywords.sh,v 1.11 2013/03/01 18:25:17 joerg Exp $
# @(#)keywords 8.2 (Berkeley) 3/19/94
#
# WARNING! If you change this file, re-run it!
# This program requires "new" awk (or GNU awk).
awk=${AWK:-awk}
cat << _EOF_ > _keywords.t1
add
atalk
blackhole
change
cloned
cloning
delete
dst
expire
flush
gateway
genmask
get
host
hopcount
iface
interface
ifa
ifp
inet
inet6
link
llinfo
lock
lockrest
mask
monitor
mtu
net
netmask
nostatic
prefixlen
proto1
proto2
recvpipe
reject
rtt
rttvar
sa
sendpipe
show
ssthresh
static
x25
xns
xresolve
flushall
nocloned
nocloning
noblackhole
noreject
mpls
tag
proxy
_EOF_
################################################################
# Setup
################################################################
# This creates a stream of:
# keyword KEYWORD
# (lower case, upper case).
tr a-z A-Z < _keywords.t1 |
paste _keywords.t1 - > _keywords.t2
################################################################
# Generate the h file
################################################################
exec > keywords.h
echo '/* $'NetBSD'$ */
/* WARNING! This file was generated by keywords.sh */
extern struct keytab {
const char *kt_cp;
int kt_i;
} keywords[];
' # defines follow
$awk '{
printf("#define\tK_%s\t%d\n", $2, NR);
}' < _keywords.t2
################################################################
# Generate the c file
################################################################
exec > keywords.c
echo '/* $'NetBSD'$ */
/* WARNING! This file was generated by keywords.sh */
#include "keywords.h"
struct keytab keywords[] = {
' # initializers follow
$awk '{
printf("\t{\"%s\", K_%s},\n", $1, $2);
}' < _keywords.t2
echo ' {0, 0}
};
' # tail
################################################################
# Cleanup
################################################################
rm -f _keywords.t1 _keywords.t2
exit 0

73
sbin/route/prog_ops.h Normal file
View File

@ -0,0 +1,73 @@
/* $NetBSD: prog_ops.h,v 1.3 2014/11/06 21:29:32 christos Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _PROG_OPS_H_
#define _PROG_OPS_H_
#include <sys/types.h>
#ifndef CRUNCHOPS
/* XXX: Keep same order with netstat! */
struct prog_ops {
int (*op_init)(void);
int (*op_sysctl)(const int *, u_int, void *, size_t *,
const void *, size_t);
int (*op_socket)(int, int, int);
int (*op_open)(const char *, int, ...);
pid_t (*op_getpid)(void);
ssize_t (*op_read)(int, void *, size_t);
ssize_t (*op_write)(int, const void *, size_t);
int (*op_shutdown)(int, int);
};
extern const struct prog_ops prog_ops;
#define prog_init prog_ops.op_init
#define prog_socket prog_ops.op_socket
#define prog_open prog_ops.op_open
#define prog_getpid prog_ops.op_getpid
#define prog_read prog_ops.op_read
#define prog_write prog_ops.op_write
#define prog_sysctl prog_ops.op_sysctl
#define prog_shutdown prog_ops.op_shutdown
#else
#define prog_init ((int (*)(void))NULL)
#define prog_socket socket
#define prog_open open
#define prog_getpid getpid
#define prog_read read
#define prog_write write
#define prog_sysctl sysctl
#define prog_shutdown shutdown
#endif
#endif /* _PROG_OPS_H_ */

449
sbin/route/route.8 Normal file
View File

@ -0,0 +1,449 @@
.\" $NetBSD: route.8,v 1.55 2015/03/23 18:33:17 roy Exp $
.\"
.\" Copyright (c) 1983, 1991, 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. 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.
.\"
.\" @(#)route.8 8.4 (Berkeley) 6/1/94
.\"
.Dd March 19, 2015
.Dt ROUTE 8
.Os
.Sh NAME
.Nm route
.Nd manually manipulate the routing tables
.Sh SYNOPSIS
.Nm
.Op Fl dfLnqSsTtv
.Ar command
.Oo
.Op Ar modifiers
.Ar args
.Oc
.Sh DESCRIPTION
.Nm
is a utility used to manually manipulate the network
routing tables.
Except for setting up the default route, it is normally not needed,
as a system routing table management daemon such as
.Xr routed 8 ,
should tend to this task.
.Pp
.Nm
can be used to modify nearly any aspect of the routing policy,
except packet forwarding, which can be manipulated through the
.Xr sysctl 8
command.
.Pp
The
.Nm
utility supports a limited number of general options,
but a rich command language, enabling the user to specify
any arbitrary request that could be delivered via the
programmatic interface discussed in
.Xr route 4 .
.Pp
.Bl -tag -width Ds
.It Fl d
Turn on debugging
.It Fl f
Remove all routes (as per
.Cm flush ) .
If used in conjunction with the
.Cm add ,
.Cm change ,
.Cm delete
or
.Cm get
commands,
.Nm
removes the routes before performing the command.
.It Fl L
Don't show link layer entries in routing table.
.It Fl n
Bypasses attempts to print host and network names symbolically
when reporting actions.
(The process of translating between symbolic
names and numerical equivalents can be quite time consuming, and
may require correct operation of the network; thus it may be expedient
to forgo this, especially when attempting to repair networking operations).
.It Fl q
Suppress all output from commands that manipulate the routing table.
.It Fl S
Print a space when a flag is missing so that flags are vertically aligned
instead of printing the flags that are set as a contiguous string.
.It Fl s
(short) Suppresses all output from a
.Cm get
command except for the actual gateway that will be used.
How the gateway is printed depends on the type of route being looked up.
.It Fl T
Show tags in the route display.
.It Fl t
Test only, don't perform any actions.
.It Fl v
(verbose) Print additional details.
.El
.Pp
The
.Nm
utility provides several commands:
.Pp
.Bl -tag -width Fl -compact
.It Cm add
Add a route.
.It Cm flush
Remove all routes.
.It Cm flushall
Remove all routes including the default gateway.
.It Cm delete
Delete a specific route.
.It Cm change
Change aspects of a route (such as its gateway).
.It Cm get
Lookup and display the route for a destination.
.It Cm show
Print out the route table similar to "netstat \-r" (see
.Xr netstat 1 ) .
.It Cm monitor
Continuously report any changes to the routing information base,
routing lookup misses, or suspected network partitionings.
.El
.Pp
The monitor command has the syntax
.Pp
.Bd -filled -offset indent -compact
.Nm
.Op Fl n
.Cm monitor
.Ed
.Pp
The flush command has the syntax
.Pp
.Bd -filled -offset indent -compact
.Nm
.Op Fl n
.Cm flush
.Op Ar family
.Ed
.Pp
If the
.Cm flush
command is specified,
.Nm
will ``flush'' the routing tables of all gateway entries.
When the address family is specified by any of the
.Fl xns ,
.Fl atalk ,
.Fl inet ,
.Fl inet6 ,
or
.Fl mpls
modifiers, only routes having destinations with addresses in the
delineated family will be manipulated.
.Pp
The other commands have the following syntax:
.Pp
.Bd -filled -offset indent -compact
.Nm
.Op Fl n
.Ar command
.Op Fl net No \&| Fl host
.Ar destination gateway
.Ed
.Pp
where
.Ar destination
is the destination host or network, and
.Ar gateway
is the next-hop intermediary via which packets should be routed.
Routes to a particular host may be distinguished from those to
a network by interpreting the Internet address specified as the
.Ar destination
argument.
The optional modifiers
.Fl net
and
.Fl host
force the destination to be interpreted as a network or a host, respectively.
Otherwise, if the
.Ar destination
has a ``local address part'' of
.Dv INADDR_ANY ,
or if the
.Ar destination
is the symbolic name of a network, then the route is
assumed to be to a network; otherwise, it is presumed to be a
route to a host.
Optionally, the
.Ar destination
can also be specified in the
.Ar net Ns / Ns Ar bits
format.
.Pp
For example,
.Li 128.32
is interpreted as
.Fl host Li 128.0.0.32 ;
.Li 128.32.130
is interpreted as
.Fl host Li 128.32.0.130 ;
.Fl net Li 128.32
is interpreted as
.Li 128.32.0.0 ;
and
.Fl net Li 128.32.130
is interpreted as
.Li 128.32.130.0 .
.Pp
The keyword
.Cm default
can be used as the
.Ar destination
to set up a default route to a smart
.Ar gateway .
If no other routes match, this default route will be used as a last resort.
.Pp
If the destination is directly reachable
via an interface requiring
no intermediary system to act as a gateway, the
.Fl interface
modifier should be specified;
the gateway given is the address of this host on the common network,
indicating the interface to be used for transmission.
.Pp
The optional modifiers
.Fl xns ,
.Fl atalk ,
and
.Fl link
specify that all subsequent addresses are in the
.Tn XNS ,
or
.Tn AppleTalk
address families,
or are specified as link-level addresses in the form described in
.Xr link_addr 3 ,
and the names must be numeric specifications rather than
symbolic names.
.Pp
The optional modifier
.Fl tag
specifies an address associated with the route.
How the address is used is specific to the address family of
the destination and the interface used to forward the packet.
Currently route tags are consumed only by the
.Xr mpls 4
stack; therefore
.Nm
assumes that the subsequent addresses are in the
.Tn MPLS
address family.
See
.Xr mpls 4
for examples of setting routes involving MPLS.
.Pp
The optional
.Fl netmask
qualifier is intended
to achieve the effect of an
.Tn ESIS
redirect with the netmask option,
or to manually add subnet routes with
netmasks different from that of the implied network interface
(as would otherwise be communicated using the OSPF or ISIS routing protocols).
One specifies an additional ensuing address parameter
(to be interpreted as a network mask).
The implicit network mask generated in the
.Dv AF_INET
case
can be overridden by making sure this option follows the destination parameter.
.Fl prefixlen
is also available for similar purpose, in IPv4 and IPv6 case.
.Pp
Routes have associated flags which influence operation of the protocols
when sending to destinations matched by the routes.
These flags are displayed using the following ID characters in the routing
display and may be set (or sometimes cleared)
by indicating the following corresponding modifiers:
.Bl -column "ID" "xnoblackhole" "xRTF_BLACKHOLE" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
.It Sy "ID" Ta Sy "Modifier" Ta Sy " Flag Bit" Ta Sy "Description"
.It Li " " Ta -iface Ta ~RTF_GATEWAY Ta destination is directly reachable
.It Li 1 Ta -proto1 Ta " RTF_PROTO1" Ta set protocol specific flag #1
.It Li 2 Ta -proto2 Ta " RTF_PROTO2" Ta set protocol specific flag #2
.It Li B Ta -blackhole Ta " RTF_BLACKHOLE" Ta discard pkts (during updates)
.It Li b Ta "" Ta " RTF_BROADCAST" Ta Route represents a broadcast address
.It Li " " Ta -noblackhole Ta ~RTF_BLACKHOLE Ta clear blackhole flag
.It Li C Ta -cloning Ta " RTF_CLONING" Ta generates a new route on use
.It Li " " Ta -nocloning Ta ~RTF_CLONING Ta stop generating new routes on use
.It Li c Ta -cloned Ta " RTF_CLONED" Ta route generated by RTF_CLONING
.It Li " " Ta -nocloned Ta ~RTF_CLONED Ta deny removal with RTF_CLONING
.It Li D Ta "" Ta " RTF_DYNAMIC" Ta created dynamically (redirect)
.It Li G Ta "" Ta " RTF_GATEWAY" Ta forwarded to dest by intermediary
.It Li H Ta "" Ta " RTF_HOST" Ta host entry (net otherwise)
.It Li L Ta -llinfo Ta " RTF_LLINFO" Ta translate proto to link addr
.It Li l Ta "" Ta " RTF_LOCAL" Ta Route represents a local address
.It Li M Ta "" Ta " RTF_MODIFIED" Ta modified dynamically (redirect)
.It Li p Ta -proxy Ta " RTF_ANNOUNCE" Ta make entry a link level proxy
.It Li R Ta -reject Ta " RTF_REJECT" Ta send ICMP unreachable on match
.It Li " " Ta -noreject Ta ~RTF_REJECT Ta clear reject flag
.It Li S Ta -static Ta " RTF_STATIC" Ta manually added route
.It Li " " Ta -nostatic Ta ~RTF_STATIC Ta pretend route added automatically
.It Li U Ta "" Ta " RTF_UP" Ta route usable
.It Li X Ta -xresolve Ta " RTF_XRESOLVE" Ta emit mesg on use (for ext lookup)
.El
.Pp
The optional modifiers
.Fl rtt ,
.Fl rttvar ,
.Fl sendpipe ,
.Fl recvpipe ,
.Fl mtu ,
.Fl hopcount ,
.Fl expire ,
and
.Fl ssthresh
provide initial values to quantities maintained in the routing entry
by transport level protocols, such as TCP or TP4.
These may be individually locked by preceding each such modifier to
be locked by
the
.Fl lock
meta-modifier, or one can
specify that all ensuing metrics may be locked by the
.Fl lockrest
meta-modifier.
.Pp
In a
.Cm change
or
.Cm add
command where the destination and gateway are not sufficient to specify
the route the
.Fl ifp
or
.Fl ifa
modifiers may be used to determine the interface or interface address.
.Pp
All symbolic names specified for a
.Ar destination
or
.Ar gateway
are looked up first as a host name using
.Xr gethostbyname 3 .
If this lookup fails,
.Xr getnetbyname 3
is then used to interpret the name as that of a network.
.Pp
.Nm
uses a routing socket and the new message types
.Dv RTM_ADD ,
.Dv RTM_DELETE ,
.Dv RTM_GET ,
and
.Dv RTM_CHANGE .
As such, only the super-user may modify
the routing tables.
.Sh EXIT STATUS
The
.Nm
utility exits 0 on success, and \*[Gt]0 if an error occurs.
This includes the use of the
.Cm get
command to look up a route that is incomplete.
.Sh EXAMPLES
This sets the default route to 192.168.0.1:
.Dl route add default 192.168.0.1
This shows all routes, without DNS resolution (this is useful if the
DNS is not available):
.Dl route -n show
To install a static route through 10.200.0.1 to reach the network
192.168.1.0/28, use this:
.Dl route add -net 192.168.1.0 -netmask 255.255.255.240 10.200.0.1
.Sh DIAGNOSTICS
.Bl -tag -width Ds
.It Sy "add [host \&| network ] %s: gateway %s flags %x"
The specified route is being added to the tables.
The values printed are from the routing table entry supplied in the
.Xr ioctl 2
call.
If the gateway address used was not the primary address of the gateway
(the first one returned by
.Xr gethostbyname 3 ) ,
the gateway address is printed numerically as well as symbolically.
.It Sy "delete [ host \&| network ] %s: gateway %s flags %x"
As above, but when deleting an entry.
.It Sy "%s %s done"
When the
.Cm flush
command is specified, each routing table entry deleted
is indicated with a message of this form.
.It Sy "Network is unreachable"
An attempt to add a route failed because the gateway listed was not
on a directly-connected network.
The next-hop gateway must be given.
.It Sy "not in table"
A delete operation was attempted for an entry which
wasn't present in the tables.
.It Sy "routing table overflow"
An add operation was attempted, but the system was
low on resources and was unable to allocate memory
to create the new entry.
.It Sy "Permission denied"
The attempted operation is privileged.
Only root may modify the routing tables.
These privileges are enforced by the kernel.
.El
.Sh SEE ALSO
.Xr mpls 4 ,
.Xr netintro 4 ,
.Xr route 4 ,
.Xr routed 8 ,
.Xr sysctl 8
.\" .Xr XNSrouted 8
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.2 .
IPv6 support was added by WIDE/KAME project.
.Sh BUGS
The first paragraph may have slightly exaggerated
.Xr routed 8 Ns 's
abilities.
.Pp
Some uses of the
.Fl ifa
or
.Fl ifp
modifiers with the add command will incorrectly fail with a
.Dq Network is unreachable
message if there is no default route.
See case
.Dv RTM_ADD
in
.Pa sys/net/rtsock.c:route_output
for details.

1809
sbin/route/route.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
/* $NetBSD: route_hostops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: route_hostops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $");
#endif /* !lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <fcntl.h>
#include <unistd.h>
#include "prog_ops.h"
const struct prog_ops prog_ops = {
.op_socket = socket,
.op_open = open,
.op_getpid = getpid,
.op_read = read,
.op_write = write,
.op_sysctl = sysctl,
.op_shutdown = shutdown,
};

View File

@ -0,0 +1,58 @@
/* $NetBSD: route_rumpops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: route_rumpops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $");
#endif /* !lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include <rump/rumpclient.h>
#include "prog_ops.h"
const struct prog_ops prog_ops = {
.op_init = rumpclient_init,
.op_socket = rump_sys_socket,
.op_open = rump_sys_open,
.op_getpid = rump_sys_getpid,
.op_read = rump_sys_read,
.op_write = rump_sys_write,
.op_sysctl = rump_sys___sysctl,
.op_shutdown = rump_sys_shutdown,
};

806
sbin/route/rtutil.c Normal file
View File

@ -0,0 +1,806 @@
/* $NetBSD: rtutil.c,v 1.6 2015/03/23 18:33:17 roy Exp $ */
/* $OpenBSD: show.c,v 1.1 2006/05/27 19:16:37 claudio Exp $ */
/*
* Copyright (c) 1983, 1988, 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. 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.
*/
#include <sys/param.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/pfvar.h>
#include <net/pfkeyv2.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netatalk/at.h>
#include <netmpls/mpls.h>
#include <arpa/inet.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "prog_ops.h"
#include "rtutil.h"
#define PLEN (LONG_BIT / 4 + 2)
#define PFKEYV2_CHUNK sizeof(u_int64_t)
static char *link_print(const struct sockaddr *);
/*
* Definitions for showing gateway flags.
*/
struct bits {
int b_mask;
char b_val;
};
static const struct bits bits[] = {
{ RTF_UP, 'U' },
{ RTF_GATEWAY, 'G' },
{ RTF_HOST, 'H' },
{ RTF_REJECT, 'R' },
{ RTF_BLACKHOLE, 'B' },
{ RTF_DYNAMIC, 'D' },
{ RTF_MODIFIED, 'M' },
{ RTF_DONE, 'd' }, /* Completed -- for routing messages only */
{ RTF_MASK, 'm' }, /* Mask Present -- for routing messages only */
{ RTF_CLONING, 'C' },
{ RTF_XRESOLVE, 'X' },
{ RTF_LLINFO, 'L' },
{ RTF_STATIC, 'S' },
{ RTF_PROTO1, '1' },
{ RTF_PROTO2, '2' },
/* { RTF_PROTO3, '3' }, */
{ RTF_CLONED, 'c' },
/* { RTF_JUMBO, 'J' }, */
{ RTF_ANNOUNCE, 'p' },
{ RTF_LOCAL, 'l'},
{ RTF_BROADCAST, 'b'},
{ 0, 0 }
};
#ifndef SMALL
static void p_tag(const struct sockaddr *sa);
#endif
static void p_rtentry(struct rt_msghdr *, int, int);
/*
* Print routing tables.
*/
void
p_rttables(int paf, int flags, int pflags, int interesting)
{
struct rt_msghdr *rtm;
char *buf = NULL, *next, *lim = NULL;
size_t needed;
int mib[6];
struct sockaddr *sa;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = paf;
mib[4] = NET_RT_DUMP;
mib[5] = 0;
if (prog_sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if (needed > 0) {
if ((buf = malloc(needed)) == 0)
err(1, NULL);
if (prog_sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
err(1, "sysctl of routing table");
lim = buf + needed;
}
printf("Routing tables\n");
if (buf) {
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sa = (struct sockaddr *)(rtm + 1);
if ((rtm->rtm_flags & pflags) != pflags)
continue;
if (paf != AF_UNSPEC && sa->sa_family != paf)
continue;
p_rtentry(rtm, flags, interesting);
}
free(buf);
buf = NULL;
}
if (paf != 0 && paf != PF_KEY)
return;
#if 0 /* XXX-elad */
mib[0] = CTL_NET;
mib[1] = PF_KEY;
mib[2] = PF_KEY_V2;
mib[3] = NET_KEY_SPD_DUMP;
mib[4] = mib[5] = 0;
if (prog_sysctl(mib, 4, NULL, &needed, NULL, 0) == -1) {
if (errno == ENOPROTOOPT)
return;
err(1, "spd-sysctl-estimate");
}
if (needed > 0) {
if ((buf = malloc(needed)) == 0)
err(1, NULL);
if (prog_sysctl(mib, 4, buf, &needed, NULL, 0) == -1)
err(1,"sysctl of spd");
lim = buf + needed;
}
if (buf) {
printf("\nEncap:\n");
for (next = buf; next < lim; next += msg->sadb_msg_len *
PFKEYV2_CHUNK) {
msg = (struct sadb_msg *)next;
if (msg->sadb_msg_len == 0)
break;
p_pfkentry(msg);
}
free(buf);
buf = NULL;
}
#endif /* 0 */
}
/*
* column widths; each followed by one space
* width of destination/gateway column
* strlen("fe80::aaaa:bbbb:cccc:dddd@gif0") == 30, strlen("/128") == 4 = 34
* strlen("aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh") == 39
*/
#ifndef INET6
#define WID_DST(af) 18 /* width of destination column */
#define WID_GW(af) 18 /* width of gateway column */
#else
#define WID_DST(af) ((af) == AF_INET6 ? ((flags & RT_NFLAG) ? 39 : 18) : 18)
#define WID_GW(af) ((af) == AF_INET6 ? ((flags & RT_NFLAG) ? 30 : 18) : 18)
#endif
/*
* Print header for routing table columns.
*/
void
p_rthdr(int paf, int flags)
{
#ifndef SMALL
if (flags & RT_AFLAG)
printf("%-*.*s ", PLEN, PLEN, "Address");
if (paf == PF_KEY) {
printf("%-18s %-5s %-18s %-5s %-5s %-22s\n",
"Source", "Port", "Destination",
"Port", "Proto", "SA(Address/Proto/Type/Direction)");
return;
}
if (flags & RT_TFLAG) {
printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %7.7s"
" %s\n", WID_DST(paf), WID_DST(paf), "Destination",
WID_GW(paf), WID_GW(paf), "Gateway",
"Flags", "Refs", "Use", "Mtu", "Tag", "Interface");
return;
}
#endif
#ifndef SMALL
printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %s\n",
WID_DST(paf), WID_DST(paf), "Destination",
WID_GW(paf), WID_GW(paf), "Gateway",
"Flags", "Refs", "Use", "Mtu", "Interface");
#else
printf("%-*.*s %-*.*s %-6.6s\n",
WID_DST(paf), WID_DST(paf), "Destination",
WID_GW(paf), WID_GW(paf), "Gateway",
"Flags");
#endif
}
static void
get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
{
int i;
for (i = 0; i < RTAX_MAX; i++) {
if (addrs & (1 << i)) {
rti_info[i] = sa;
sa = (struct sockaddr *)((char *)(sa) +
RT_ROUNDUP(sa->sa_len));
} else
rti_info[i] = NULL;
}
}
/*
* Print a routing table entry.
*/
static void
p_rtentry(struct rt_msghdr *rtm, int flags, int interesting)
{
static int old_af = -1;
struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
struct sockaddr *mask, *rti_info[RTAX_MAX];
#ifndef SMALL
char ifbuf[IF_NAMESIZE];
#endif
if ((flags & RT_LFLAG) && (rtm->rtm_flags & RTF_LLINFO))
return;
if (old_af != sa->sa_family) {
old_af = sa->sa_family;
p_family(sa->sa_family);
p_rthdr(sa->sa_family, flags);
}
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
mask = rti_info[RTAX_NETMASK];
if ((sa = rti_info[RTAX_DST]) == NULL)
return;
p_sockaddr(sa, mask, rtm->rtm_flags, WID_DST(sa->sa_family), flags);
p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST,
WID_GW(sa->sa_family), flags);
p_flags(rtm->rtm_flags & interesting);
#if 0 /* XXX-elad */
printf("%6d %8"PRId64" ", (int)rtm->rtm_rmx.rmx_refcnt,
rtm->rtm_rmx.rmx_pksent);
#else
printf("%6s %8s ", "-", "-");
#endif
#ifndef SMALL
if (rtm->rtm_rmx.rmx_mtu)
printf("%6"PRId64, rtm->rtm_rmx.rmx_mtu);
else
printf("%6s", "-");
putchar((rtm->rtm_rmx.rmx_locks & RTV_MTU) ? 'L' : ' ');
if (flags & RT_TFLAG)
p_tag(rti_info[RTAX_TAG]);
printf(" %.16s", if_indextoname(rtm->rtm_index, ifbuf));
putchar('\n');
if (flags & RT_VFLAG)
p_rtrmx(&rtm->rtm_rmx);
#endif
}
/*
* Print address family header before a section of the routing table.
*/
void
p_family(int paf)
{
const char *afname;
switch (paf) {
case AF_INET:
afname = "Internet";
break;
#ifdef INET6
case AF_INET6:
afname = "Internet6";
break;
#endif
case PF_KEY:
afname = "Encap";
break;
case AF_APPLETALK:
afname = "AppleTalk";
break;
#ifndef SMALL
case AF_MPLS:
afname = "MPLS";
break;
#endif
default:
afname = NULL;
break;
}
if (afname)
printf("\n%s:\n", afname);
else
printf("\nProtocol Family %d:\n", paf);
}
void
p_sockaddr(const struct sockaddr *sa, const struct sockaddr *mask, int rflags,
int width, int flags)
{
char *cp;
switch (sa->sa_family) {
#ifdef INET6
case AF_INET6:
{
struct sockaddr_in6 sa6 = *(const struct sockaddr_in6 *)sa;
inet6_getscopeid(&sa6, INET6_IS_ADDR_LINKLOCAL|
INET6_IS_ADDR_MC_LINKLOCAL);
if (rflags & RTF_HOST)
cp = routename((const struct sockaddr *)&sa6, flags);
else
cp = netname((const struct sockaddr *)&sa6, mask, flags);
break;
}
#endif
default:
if ((rflags & RTF_HOST) || mask == NULL)
cp = routename(sa, flags);
else
cp = netname(sa, mask, flags);
break;
}
if (width < 0)
printf("%s", cp);
else {
if (flags & RT_NFLAG)
printf("%-*s ", width, cp);
else
printf("%-*.*s ", width, width, cp);
}
}
void
p_flags(int f)
{
char name[33], *flags;
const struct bits *p = bits;
for (flags = name; p->b_mask && flags < &name[sizeof(name) - 2]; p++)
if (p->b_mask & f)
*flags++ = p->b_val;
*flags = '\0';
printf("%-6.6s ", name);
}
#ifndef SMALL
void
p_rtrmx(const struct rt_metrics *rmx)
{
printf("\texpire %10"PRId64"%c recvpipe %10"PRIu64"%c "
"sendpipe %10"PRIu64"%c\n",
(int64_t)rmx->rmx_expire,
(rmx->rmx_locks & RTV_EXPIRE) ? 'L' : ' ', rmx->rmx_recvpipe,
(rmx->rmx_locks & RTV_RPIPE) ? 'L' : ' ', rmx->rmx_sendpipe,
(rmx->rmx_locks & RTV_SPIPE) ? 'L' : ' ');
printf("\tssthresh %10"PRIu64"%c rtt %10"PRIu64"%c "
"rttvar %10"PRIu64"%c\n", rmx->rmx_ssthresh,
(rmx->rmx_locks & RTV_SSTHRESH) ? 'L' : ' ',
rmx->rmx_rtt, (rmx->rmx_locks & RTV_RTT) ? 'L' : ' ',
rmx->rmx_rttvar, (rmx->rmx_locks & RTV_RTTVAR) ? 'L' : ' ');
printf("\thopcount %10"PRIu64"%c\n",
rmx->rmx_hopcount, (rmx->rmx_locks & RTV_HOPCOUNT) ? 'L' : ' ');
}
static void
p_tag(const struct sockaddr *sa)
{
char *line;
if (sa == NULL || sa->sa_family != AF_MPLS) {
printf("%7s", "-");
return;
}
line = mpls_ntoa(sa);
if (strlen(line) < 7)
printf("%7s", line);
else
printf("%s", line);
}
#endif
static char line[MAXHOSTNAMELEN];
static char domain[MAXHOSTNAMELEN];
char *
routename(const struct sockaddr *sa, int flags)
{
char *cp = NULL;
static int first = 1;
if (first) {
first = 0;
if (gethostname(domain, sizeof(domain)) == 0 &&
(cp = strchr(domain, '.')))
(void)strlcpy(domain, cp + 1, sizeof(domain));
else
domain[0] = '\0';
cp = NULL;
}
if (sa->sa_len == 0) {
(void)strlcpy(line, "default", sizeof(line));
return (line);
}
switch (sa->sa_family) {
case AF_INET:
return routename4(
((const struct sockaddr_in *)sa)->sin_addr.s_addr,
flags);
#ifdef INET6
case AF_INET6:
{
struct sockaddr_in6 sin6;
memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6, sa, sa->sa_len);
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_family = AF_INET6;
if (sa->sa_len == sizeof(struct sockaddr_in6))
#if defined(__minix)
/*
* Local MINIX3 fix for a NetBSD issue: inet6_getscopeid()
* is sometimes called twice in a row when printing routing
* tables, discarding the scope ID the second time..
*/
if (sin6.sin6_scope_id == 0)
#endif /* defined(__minix) */
inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL|
INET6_IS_ADDR_MC_LINKLOCAL);
return routename6(&sin6, flags);
}
#endif
case AF_LINK:
return link_print(sa);
#ifndef SMALL
case AF_MPLS:
return mpls_ntoa(sa);
case AF_APPLETALK:
(void)snprintf(line, sizeof(line), "atalk %d.%d",
((const struct sockaddr_at *)sa)->sat_addr.s_net,
((const struct sockaddr_at *)sa)->sat_addr.s_node);
break;
#endif
#if 0 /* XXX-elad */
case AF_UNSPEC:
if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) {
static char name[RTLABEL_LEN];
struct sockaddr_rtlabel *sr;
sr = (struct sockaddr_rtlabel *)sa;
strlcpy(name, sr->sr_label, sizeof(name));
return (name);
}
/* FALLTHROUGH */
#endif
default:
(void)snprintf(line, sizeof(line), "(%d) %s",
sa->sa_family, any_ntoa(sa));
break;
}
return (line);
}
char *
routename4(in_addr_t in, int flags)
{
const char *cp = NULL;
struct in_addr ina;
struct hostent *hp;
if (in == INADDR_ANY)
cp = "default";
if (!cp && (flags & RT_NFLAG) == 0) {
if ((hp = gethostbyaddr((char *)&in,
sizeof(in), AF_INET)) != NULL) {
char *p;
if ((p = strchr(hp->h_name, '.')) &&
!strcmp(p + 1, domain))
*p = '\0';
cp = hp->h_name;
}
}
ina.s_addr = in;
strlcpy(line, cp ? cp : inet_ntoa(ina), sizeof(line));
return (line);
}
#ifdef INET6
char *
routename6(const struct sockaddr_in6 *sin6, int flags)
{
int niflags = 0;
if ((flags & RT_NFLAG))
niflags |= NI_NUMERICHOST;
else
niflags |= NI_NOFQDN;
if (getnameinfo((const struct sockaddr *)sin6, sin6->sin6_len,
line, sizeof(line), NULL, 0, niflags) != 0)
strncpy(line, "invalid", sizeof(line));
return (line);
}
#endif
/*
* Return the name of the network whose address is given.
* The address is assumed to be that of a net or subnet, not a host.
*/
char *
netname4(const struct sockaddr_in* sa4, const struct sockaddr_in *mask, int flags)
{
const char *cp = NULL;
struct netent *np = NULL;
int mbits;
in_addr_t in = sa4->sin_addr.s_addr;
if (mask) {
in_addr_t m = mask->sin_addr.s_addr ;
m = ntohl(m);
mbits = m ? 33 - ffs(m) : 0;
} else
mbits = 0;
in = ntohl(in);
if (in == INADDR_ANY && !mbits)
cp = "default";
else if (!(flags & RT_NFLAG) && in != INADDR_ANY) {
if ((np = getnetbyaddr(in, AF_INET)) != NULL)
cp = np->n_name;
}
if (cp)
strlcpy(line, cp, sizeof(line));
#define C(x) ((x) & 0xff)
else if (mbits < 9)
snprintf(line, sizeof(line), "%u/%d", C(in >> 24), mbits);
else if (mbits < 17)
snprintf(line, sizeof(line), "%u.%u/%d",
C(in >> 24) , C(in >> 16), mbits);
else if (mbits < 25)
snprintf(line, sizeof(line), "%u.%u.%u/%d",
C(in >> 24), C(in >> 16), C(in >> 8), mbits);
else
snprintf(line, sizeof(line), "%u.%u.%u.%u/%d", C(in >> 24),
C(in >> 16), C(in >> 8), C(in), mbits);
#undef C
return line;
}
#ifdef INET6
char *
netname6(const struct sockaddr_in6 *sa6, const struct sockaddr_in6 *mask, int flags)
{
struct sockaddr_in6 sin6;
const u_char *p;
int masklen, final = 0, illegal = 0;
int i, lim, flag, error;
char hbuf[NI_MAXHOST];
sin6 = *sa6;
flag = 0;
masklen = 0;
if (mask) {
lim = mask->sin6_len - offsetof(struct sockaddr_in6, sin6_addr);
if (lim < 0)
lim = 0;
else if (lim > (int)sizeof(struct in6_addr))
lim = sizeof(struct in6_addr);
for (p = (const u_char *)&mask->sin6_addr, i = 0; i < lim; p++) {
if (final && *p) {
illegal++;
sin6.sin6_addr.s6_addr[i++] = 0x00;
continue;
}
switch (*p & 0xff) {
case 0xff:
masklen += 8;
break;
case 0xfe:
masklen += 7;
final++;
break;
case 0xfc:
masklen += 6;
final++;
break;
case 0xf8:
masklen += 5;
final++;
break;
case 0xf0:
masklen += 4;
final++;
break;
case 0xe0:
masklen += 3;
final++;
break;
case 0xc0:
masklen += 2;
final++;
break;
case 0x80:
masklen += 1;
final++;
break;
case 0x00:
final++;
break;
default:
final++;
illegal++;
break;
}
if (!illegal)
sin6.sin6_addr.s6_addr[i++] &= *p;
else
sin6.sin6_addr.s6_addr[i++] = 0x00;
}
while (i < (int)sizeof(struct in6_addr))
sin6.sin6_addr.s6_addr[i++] = 0x00;
} else
masklen = 128;
if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)) {
snprintf(line, sizeof(line), "default");
return (line);
}
if (illegal)
warnx("illegal prefixlen");
if (flags & RT_NFLAG)
flag |= NI_NUMERICHOST;
error = getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
hbuf, sizeof(hbuf), NULL, 0, flag);
if (error)
snprintf(hbuf, sizeof(hbuf), "invalid");
snprintf(line, sizeof(line), "%s/%d", hbuf, masklen);
return (line);
}
#endif
/*
* Return the name of the network whose address is given.
* The address is assumed to be that of a net or subnet, not a host.
*/
char *
netname(const struct sockaddr *sa, const struct sockaddr *mask, int flags)
{
switch (sa->sa_family) {
case AF_INET:
return netname4((const struct sockaddr_in *)sa,
(const struct sockaddr_in *)mask, flags);
#ifdef INET6
case AF_INET6:
return netname6((const struct sockaddr_in6 *)sa,
(const struct sockaddr_in6 *)mask, flags);
#endif
case AF_LINK:
return link_print(sa);
default:
snprintf(line, sizeof(line), "af %d: %s",
sa->sa_family, any_ntoa(sa));
break;
}
return (line);
}
static const char hexlist[] = "0123456789abcdef";
char *
any_ntoa(const struct sockaddr *sa)
{
static char obuf[240];
const char *in = sa->sa_data;
char *out = obuf;
int len = sa->sa_len - offsetof(struct sockaddr, sa_data);
*out++ = 'Q';
do {
*out++ = hexlist[(*in >> 4) & 15];
*out++ = hexlist[(*in++) & 15];
*out++ = '.';
} while (--len > 0 && (out + 3) < &obuf[sizeof(obuf) - 1]);
out[-1] = '\0';
return (obuf);
}
static char *
link_print(const struct sockaddr *sa)
{
const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)sa;
const u_char *lla = (const u_char *)sdl->sdl_data + sdl->sdl_nlen;
if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 &&
sdl->sdl_slen == 0) {
(void)snprintf(line, sizeof(line), "link#%d", sdl->sdl_index);
return (line);
}
switch (sdl->sdl_type) {
case IFT_ETHER:
case IFT_CARP:
return ether_ntoa((const struct ether_addr *)lla);
default:
return link_ntoa(sdl);
}
}
#ifndef SMALL
char *
mpls_ntoa(const struct sockaddr *sa)
{
static char obuf[16];
size_t olen;
const union mpls_shim *pms;
union mpls_shim ms;
int psize = sizeof(struct sockaddr_mpls);
pms = &((const struct sockaddr_mpls*)sa)->smpls_addr;
ms.s_addr = ntohl(pms->s_addr);
snprintf(obuf, sizeof(obuf), "%u", ms.shim.label);
while(psize < sa->sa_len) {
pms++;
ms.s_addr = ntohl(pms->s_addr);
olen = strlen(obuf);
snprintf(obuf + olen, sizeof(obuf) - olen, ",%u",
ms.shim.label);
psize+=sizeof(ms);
}
return obuf;
}
#endif
void
p_addr(const struct sockaddr *sa, const struct sockaddr *mask, int rflags, int flags)
{
p_sockaddr(sa, mask, rflags, WID_DST(sa->sa_family), flags);
}
void
p_gwaddr(const struct sockaddr *sa, int gwaf, int flags)
{
p_sockaddr(sa, 0, RTF_HOST, WID_GW(gwaf), flags);
}

59
sbin/route/rtutil.h Normal file
View File

@ -0,0 +1,59 @@
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* 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 NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#define RT_AFLAG __BIT(0) /* show address field */
#define RT_TFLAG __BIT(1) /* show tag field */
#define RT_VFLAG __BIT(2) /* show verbose statistics */
#define RT_NFLAG __BIT(3) /* numeric output */
#define RT_LFLAG __BIT(4) /* don't show LLINFO entries */
void p_rttables(int, int, int, int);
void p_rthdr(int, int);
void p_family(int);
void p_sockaddr(const struct sockaddr *, const struct sockaddr *, int, int, int);
void p_flags(int);
struct rt_metrics;
void p_rtrmx(const struct rt_metrics *);
void p_addr(const struct sockaddr *sa, const struct sockaddr *mask, int, int);
void p_gwaddr(const struct sockaddr *sa, int, int);
char *routename(const struct sockaddr *sa, int);
char *routename4(in_addr_t, int);
#ifdef INET6
char *routename6(const struct sockaddr_in6 *, int);
char *netname6(const struct sockaddr_in6 *, const struct sockaddr_in6 *, int);
#endif
char *netname(const struct sockaddr *, const struct sockaddr *, int);
char *netname4(const struct sockaddr_in *, const struct sockaddr_in *, int);
char *mpls_ntoa(const struct sockaddr *);
char *any_ntoa(const struct sockaddr *);

144
sbin/route/show.c Normal file
View File

@ -0,0 +1,144 @@
/* $NetBSD: show.c,v 1.48 2015/03/23 18:33:17 roy Exp $ */
/*
* Copyright (c) 1983, 1988, 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. 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.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94";
#else
__RCSID("$NetBSD: show.c,v 1.48 2015/03/23 18:33:17 roy Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netmpls/mpls.h>
#include <sys/sysctl.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include "keywords.h"
#include "rtutil.h"
#include "extern.h"
#include "prog_ops.h"
void
parse_show_opts(int argc, char * const *argv, int *afp, int *flagsp,
const char **afnamep, bool nolink)
{
const char *afname = "unspec";
int af, flags;
flags = 0;
af = AF_UNSPEC;
for (; argc >= 2; argc--) {
if (*argv[argc - 1] != '-')
goto bad;
switch (keyword(argv[argc - 1] + 1)) {
case K_HOST:
flags |= RTF_HOST;
break;
case K_LLINFO:
flags |= RTF_LLINFO;
break;
case K_INET:
af = AF_INET;
afname = argv[argc - 1] + 1;
break;
#ifdef INET6
case K_INET6:
af = AF_INET6;
afname = argv[argc - 1] + 1;
break;
#endif
#ifndef SMALL
case K_ATALK:
af = AF_APPLETALK;
afname = argv[argc - 1] + 1;
break;
case K_MPLS:
af = AF_MPLS;
afname = argv[argc - 1] + 1;
break;
#endif /* SMALL */
case K_LINK:
if (nolink)
goto bad;
af = AF_LINK;
afname = argv[argc - 1] + 1;
break;
default:
goto bad;
}
}
switch (argc) {
case 1:
case 0:
break;
default:
bad:
usage(argv[argc - 1]);
}
if (afnamep != NULL)
*afnamep = afname;
*afp = af;
*flagsp = flags;
}
/*
* Print routing tables.
*/
void
show(int argc, char *const *argv, int flags)
{
int af, rflags;
static int interesting = RTF_UP | RTF_GATEWAY | RTF_HOST |
RTF_REJECT | RTF_LLINFO | RTF_LOCAL | RTF_BROADCAST;
parse_show_opts(argc, argv, &af, &rflags, NULL, true);
p_rttables(af, flags, rflags, interesting);
}