Getaddrinfo(), getnameinfo(), and etc support in libc/net.
Several udp and raw apps IPv6 support. Reviewed by: freebsd-arch, cvs-committers Obtained from: KAME project
This commit is contained in:
parent
56f680165a
commit
2958040f73
@ -62,6 +62,7 @@
|
||||
#define _NETDB_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef _PATH_HEQUIV
|
||||
# define _PATH_HEQUIV "/etc/hosts.equiv"
|
||||
@ -111,6 +112,17 @@ struct protoent {
|
||||
int p_proto; /* protocol # */
|
||||
};
|
||||
|
||||
struct addrinfo {
|
||||
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
|
||||
int ai_family; /* PF_xxx */
|
||||
int ai_socktype; /* SOCK_xxx */
|
||||
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
size_t ai_addrlen; /* length of ai_addr */
|
||||
char *ai_canonname; /* canonical name for hostname */
|
||||
struct sockaddr *ai_addr; /* binary address */
|
||||
struct addrinfo *ai_next; /* next structure in linked list */
|
||||
};
|
||||
|
||||
/*
|
||||
* Error return codes from gethostbyname() and gethostbyaddr()
|
||||
* (left in extern int h_errno).
|
||||
@ -124,15 +136,74 @@ struct protoent {
|
||||
#define NO_DATA 4 /* Valid name, no data record of requested type */
|
||||
#define NO_ADDRESS NO_DATA /* no address, look for MX record */
|
||||
|
||||
/*
|
||||
* Error return codes from getaddrinfo()
|
||||
*/
|
||||
#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
|
||||
#define EAI_AGAIN 2 /* temporary failure in name resolution */
|
||||
#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
|
||||
#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
|
||||
#define EAI_FAMILY 5 /* ai_family not supported */
|
||||
#define EAI_MEMORY 6 /* memory allocation failure */
|
||||
#define EAI_NODATA 7 /* no address associated with hostname */
|
||||
#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
|
||||
#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
|
||||
#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
|
||||
#define EAI_SYSTEM 11 /* system error returned in errno */
|
||||
#define EAI_BADHINTS 12
|
||||
#define EAI_PROTOCOL 13
|
||||
#define EAI_RESNULL 14
|
||||
#define EAI_MAX 15
|
||||
|
||||
/*
|
||||
* Flag values for getaddrinfo()
|
||||
*/
|
||||
#define AI_PASSIVE 0x00000001 /* get address to use bind() */
|
||||
#define AI_CANONNAME 0x00000002 /* fill ai_canonname */
|
||||
#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */
|
||||
/* valid flags for addrinfo */
|
||||
#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
|
||||
|
||||
#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
|
||||
#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
|
||||
#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */
|
||||
#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */
|
||||
/* special recommended flags for getipnodebyname */
|
||||
#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
|
||||
|
||||
/*
|
||||
* Constants for getnameinfo()
|
||||
*/
|
||||
#define NI_MAXHOST 1025
|
||||
#define NI_MAXSERV 32
|
||||
|
||||
/*
|
||||
* Flag values for getnameinfo()
|
||||
*/
|
||||
#define NI_NOFQDN 0x00000001
|
||||
#define NI_NUMERICHOST 0x00000002
|
||||
#define NI_NAMEREQD 0x00000004
|
||||
#define NI_NUMERICSERV 0x00000008
|
||||
#define NI_DGRAM 0x00000010
|
||||
#define NI_WITHSCOPEID 0x00000020
|
||||
|
||||
/*
|
||||
* Scope delimit character
|
||||
*/
|
||||
#define SCOPE_DELIMITER '@'
|
||||
|
||||
__BEGIN_DECLS
|
||||
void endhostent __P((void));
|
||||
void endnetent __P((void));
|
||||
void endprotoent __P((void));
|
||||
void endservent __P((void));
|
||||
void freehostent __P((struct hostent *));
|
||||
struct hostent *gethostbyaddr __P((const char *, int, int));
|
||||
struct hostent *gethostbyname __P((const char *));
|
||||
struct hostent *gethostbyname2 __P((const char *, int));
|
||||
struct hostent *gethostent __P((void));
|
||||
struct hostent *getipnodebyaddr __P((const void *, size_t, int, int *));
|
||||
struct hostent *getipnodebyname __P((const char *, int, int, int *));
|
||||
struct netent *getnetbyaddr __P((unsigned long, int));
|
||||
struct netent *getnetbyname __P((const char *));
|
||||
struct netent *getnetent __P((void));
|
||||
@ -148,6 +219,12 @@ void sethostent __P((int));
|
||||
/* void sethostfile __P((const char *)); */
|
||||
void setnetent __P((int));
|
||||
void setprotoent __P((int));
|
||||
int getaddrinfo __P((const char *, const char *,
|
||||
const struct addrinfo *, struct addrinfo **));
|
||||
int getnameinfo __P((const struct sockaddr *, size_t, char *,
|
||||
size_t, char *, size_t, int));
|
||||
void freeaddrinfo __P((struct addrinfo *));
|
||||
char *gai_strerror __P((int));
|
||||
void setservent __P((int));
|
||||
|
||||
/*
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
@ -116,6 +117,21 @@ struct __res_state {
|
||||
char pad[72]; /* on an i386 this means 512b total */
|
||||
};
|
||||
|
||||
/* for INET6 */
|
||||
/*
|
||||
* replacement of __res_state, separated to keep binary compatibility.
|
||||
*/
|
||||
struct __res_state_ext {
|
||||
struct sockaddr_storage nsaddr_list[MAXNS];
|
||||
struct {
|
||||
int af; /* address family for addr, mask */
|
||||
union {
|
||||
struct in_addr ina;
|
||||
struct in6_addr in6a;
|
||||
} addr, mask;
|
||||
} sort_list[MAXRESOLVSORT];
|
||||
};
|
||||
|
||||
/*
|
||||
* Resolver options (keep these in synch with res_debug.c, please)
|
||||
*/
|
||||
@ -181,6 +197,9 @@ struct res_sym {
|
||||
};
|
||||
|
||||
extern struct __res_state _res;
|
||||
/* for INET6 */
|
||||
extern struct __res_state_ext _res_ext;
|
||||
|
||||
extern const struct res_sym __p_class_syms[];
|
||||
extern const struct res_sym __p_type_syms[];
|
||||
|
||||
|
@ -4,15 +4,16 @@
|
||||
# machine-independent net sources
|
||||
.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/net ${.CURDIR}/../libc/net
|
||||
|
||||
SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c \
|
||||
SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c getaddrinfo.c \
|
||||
gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \
|
||||
getnameinfo.c \
|
||||
getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
|
||||
getproto.c getprotoent.c getprotoname.c getservbyname.c \
|
||||
getservbyport.c getservent.c herror.c inet_addr.c ifname.c \
|
||||
inet_lnaof.c \
|
||||
inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \
|
||||
inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \
|
||||
inet_pton.c ip6opt.c linkaddr.c map_v4v6.c ns_addr.c \
|
||||
inet_pton.c ip6opt.c linkaddr.c map_v4v6.c name6.c ns_addr.c \
|
||||
ns_name.c ns_netint.c \
|
||||
ns_ntoa.c ns_parse.c ns_print.c ns_ttl.c nsap_addr.c \
|
||||
rcmd.c recv.c res_comp.c res_data.c res_debug.c \
|
||||
@ -20,12 +21,15 @@ SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c \
|
||||
res_update.c rthdr.c send.c vars.c
|
||||
# not supported: iso_addr.c
|
||||
|
||||
CFLAGS+=-DINET6
|
||||
|
||||
# machine-dependent net sources
|
||||
.include "${.CURDIR}/../libc/${MACHINE_ARCH}/net/Makefile.inc"
|
||||
|
||||
.if ${LIB} == "c"
|
||||
MAN3+= addr2ascii.3 byteorder.3 ethers.3 gethostbyname.3 \
|
||||
getnetent.3 getprotoent.3 getservent.3 if_indextoname.3 \
|
||||
MAN3+= addr2ascii.3 byteorder.3 ethers.3 getaddrinfo.3 gethostbyname.3 \
|
||||
getipnodebyname.3 \
|
||||
getnameinfo.3 getnetent.3 getprotoent.3 getservent.3 if_indextoname.3 \
|
||||
inet.3 linkaddr.3 rcmd.3 resolver.3
|
||||
# not installed: iso_addr.3 ns.3
|
||||
|
||||
@ -34,10 +38,12 @@ MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
|
||||
byteorder.3 ntohs.3
|
||||
MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \
|
||||
ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3
|
||||
MLINKS+=getaddrinfo.3 freeaddrinfo.3 getaddrinfo.3 gai_strerror.3
|
||||
MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
|
||||
gethostbyname.3 gethostbyname2.3 gethostbyname.3 gethostent.3 \
|
||||
gethostbyname.3 herror.3 gethostbyname.3 hstrerror.3 \
|
||||
gethostbyname.3 sethostent.3
|
||||
MLINKS+=getipnodebyname.3 getipnodebyaddr.3 getipnodebyname.3 freehostent.3
|
||||
MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
|
||||
getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
|
||||
MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
|
||||
|
408
lib/libc/net/getaddrinfo.3
Normal file
408
lib/libc/net/getaddrinfo.3
Normal file
@ -0,0 +1,408 @@
|
||||
.\" Copyright (c) 1983, 1987, 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. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. 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.
|
||||
.\"
|
||||
.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
|
||||
.\" $Id: getaddrinfo.3,v 1.3 1999/10/07 08:22:04 jinmei Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 25, 1995
|
||||
.Dt GETADDRINFO 3
|
||||
.Os KAME
|
||||
.\"
|
||||
.Sh NAME
|
||||
.Nm getaddrinfo
|
||||
.Nm freeaddrinfo ,
|
||||
.Nm gai_strerror
|
||||
.Nd nodename-to-address translation in protocol-independent manner
|
||||
.\"
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/socket.h>
|
||||
.Fd #include <netdb.h>
|
||||
.Ft int
|
||||
.Fn getaddrinfo "const char *nodename" "const char *servname" \
|
||||
"const struct addrinfo *hints" "struct addrinfo **res"
|
||||
.Ft void
|
||||
.Fn freeaddrinfo "struct addrinfo *ai"
|
||||
.Ft "char *"
|
||||
.Fn gai_strerror "int ecode"
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn getaddrinfo
|
||||
function is defined for protocol-independent nodename-to-address translation.
|
||||
It performs functionality of
|
||||
.Xr gethostbyname 3
|
||||
and
|
||||
.Xr getservbyname 3 ,
|
||||
in more sophisticated manner.
|
||||
.Pp
|
||||
The addrinfo structure is defined as a result of including the
|
||||
.Li <netdb.h>
|
||||
header:
|
||||
.Bd -literal -offset
|
||||
struct addrinfo { *
|
||||
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
|
||||
int ai_family; /* PF_xxx */
|
||||
int ai_socktype; /* SOCK_xxx */
|
||||
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
size_t ai_addrlen; /* length of ai_addr */
|
||||
char *ai_canonname; /* canonical name for nodename */
|
||||
struct sockaddr *ai_addr; /* binary address */
|
||||
struct addrinfo *ai_next; /* next structure in linked list */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Fa nodename
|
||||
and
|
||||
.Fa servname
|
||||
arguments are pointers to null-terminated strings or
|
||||
.Dv NULL .
|
||||
One or both of these two arguments must be a
|
||||
.Pf non Dv -NULL
|
||||
pointer.
|
||||
In the normal client scenario, both the
|
||||
.Fa nodename
|
||||
and
|
||||
.Fa servname
|
||||
are specified.
|
||||
In the normal server scenario, only the
|
||||
.Fa servname
|
||||
is specified.
|
||||
A
|
||||
.Pf non Dv -NULL
|
||||
.Fa nodename
|
||||
string can be either a node name or a numeric host address string
|
||||
.Po
|
||||
i.e., a dotted-decimal IPv4 address or an IPv6 hex address
|
||||
.Pc .
|
||||
A
|
||||
.Pf non Dv -NULL
|
||||
.Fa servname
|
||||
string can be either a service name or a decimal port number.
|
||||
.Pp
|
||||
The caller can optionally pass an
|
||||
.Li addrinfo
|
||||
structure, pointed to by the third argument,
|
||||
to provide hints concerning the type of socket that the caller supports.
|
||||
In this
|
||||
.Fa hints
|
||||
structure all members other than
|
||||
.Fa ai_flags ,
|
||||
.Fa ai_family ,
|
||||
.Fa ai_socktype ,
|
||||
and
|
||||
.Fa ai_protocol
|
||||
must be zero or a
|
||||
.Dv NULL
|
||||
pointer.
|
||||
A value of
|
||||
.Dv PF_UNSPEC
|
||||
for
|
||||
.Fa ai_family
|
||||
means the caller will accept any protocol family.
|
||||
A value of 0 for
|
||||
.Fa ai_socktype
|
||||
means the caller will accept any socket type.
|
||||
A value of 0 for
|
||||
.Fa ai_protocol
|
||||
means the caller will accept any protocol.
|
||||
For example, if the caller handles only TCP and not UDP, then the
|
||||
.Fa ai_socktype
|
||||
member of the hints structure should be set to
|
||||
.Dv SOCK_STREAM
|
||||
when
|
||||
.Fn getaddrinfo
|
||||
is called.
|
||||
If the caller handles only IPv4 and not IPv6, then the
|
||||
.Fa ai_family
|
||||
member of the
|
||||
.Fa hints
|
||||
structure should be set to
|
||||
.Dv PF_INET
|
||||
when
|
||||
.Fn getaddrinfo
|
||||
is called.
|
||||
If the third argument to
|
||||
.Fn getaddrinfo
|
||||
is a
|
||||
.Dv NULL
|
||||
pointer, this is the same as if the caller had filled in an
|
||||
.Li addrinfo
|
||||
structure initialized to zero with
|
||||
.Fa ai_family
|
||||
set to PF_UNSPEC.
|
||||
.Pp
|
||||
Upon successful return a pointer to a linked list of one or more
|
||||
.Li addrinfo
|
||||
structures is returned through the final argument.
|
||||
The caller can process each
|
||||
.Li addrinfo
|
||||
structure in this list by following the
|
||||
.Fa ai_next
|
||||
pointer, until a
|
||||
.Dv NULL
|
||||
pointer is encountered.
|
||||
In each returned
|
||||
.Li addrinfo
|
||||
structure the three members
|
||||
.Fa ai_family ,
|
||||
.Fa ai_socktype ,
|
||||
and
|
||||
.Fa ai_protocol
|
||||
are the corresponding arguments for a call to the
|
||||
.Fn socket
|
||||
function.
|
||||
In each
|
||||
.Li addrinfo
|
||||
structure the
|
||||
.Fa ai_addr
|
||||
member points to a filled-in socket address structure whose length is
|
||||
specified by the
|
||||
.Fa ai_addrlen
|
||||
member.
|
||||
.Pp
|
||||
If the
|
||||
.Dv AI_PASSIVE
|
||||
bit is set in the
|
||||
.Fa ai_flags
|
||||
member of the
|
||||
.Fa hints
|
||||
structure, then the caller plans to use the returned socket address
|
||||
structure in a call to
|
||||
.Fn bind .
|
||||
In this case, if the
|
||||
.Fa nodename
|
||||
argument is a
|
||||
.Dv NULL
|
||||
pointer, then the IP address portion of the socket
|
||||
address structure will be set to
|
||||
.Dv INADDR_ANY
|
||||
for an IPv4 address or
|
||||
.Dv IN6ADDR_ANY_INIT
|
||||
for an IPv6 address.
|
||||
.Pp
|
||||
If the
|
||||
.Dv AI_PASSIVE
|
||||
bit is not set in the
|
||||
.Fa ai_flags
|
||||
member of the
|
||||
.Fa hints
|
||||
structure, then the returned socket address structure will be ready for a
|
||||
call to
|
||||
.Fn connect
|
||||
.Pq for a connection-oriented protocol
|
||||
or either
|
||||
.Fn connect ,
|
||||
.Fn sendto , or
|
||||
.Fn sendmsg
|
||||
.Pq for a connectionless protocol .
|
||||
In this case, if the
|
||||
.Fa nodename
|
||||
argument is a
|
||||
.Dv NULL
|
||||
pointer, then the IP address portion of the
|
||||
socket address structure will be set to the loopback address.
|
||||
.Pp
|
||||
If the
|
||||
.Dv AI_CANONNAME
|
||||
bit is set in the
|
||||
.Fa ai_flags
|
||||
member of the
|
||||
.Fa hints
|
||||
structure, then upon successful return the
|
||||
.Fa ai_canonname
|
||||
member of the first
|
||||
.Li addrinfo
|
||||
structure in the linked list will point to a null-terminated string
|
||||
containing the canonical name of the specified
|
||||
.Fa nodename .
|
||||
.Pp
|
||||
If the
|
||||
.Dv AI_NUMERICHOST
|
||||
bit is set in the
|
||||
.Fa ai_flags
|
||||
member of the
|
||||
.Fa hints
|
||||
structure, then a
|
||||
.Pf non Dv -NULL
|
||||
.Fa nodename
|
||||
string must be a numeric host address string.
|
||||
Otherwise an error of
|
||||
.Dv EAI_NONAME
|
||||
is returned.
|
||||
This flag prevents any type of name resolution service (e.g., the DNS)
|
||||
from being called.
|
||||
.Pp
|
||||
All of the information returned by
|
||||
.Fn getaddrinfo
|
||||
is dynamically allocated:
|
||||
the
|
||||
.Li addrinfo
|
||||
structures, and the socket address structures and canonical node name
|
||||
strings pointed to by the addrinfo structures.
|
||||
To return this information to the system the function
|
||||
.Fn freeaddrinfo
|
||||
is called.
|
||||
The
|
||||
.Fa addrinfo
|
||||
structure pointed to by the
|
||||
.Fa ai argument
|
||||
is freed, along with any dynamic storage pointed to by the structure.
|
||||
This operation is repeated until a
|
||||
.Dv NULL
|
||||
.Fa ai_next
|
||||
pointer is encountered.
|
||||
.Pp
|
||||
To aid applications in printing error messages based on the
|
||||
.Dv EAI_xxx
|
||||
codes returned by
|
||||
.Fn getaddrinfo ,
|
||||
.Fn gai_strerror
|
||||
is defined.
|
||||
The argument is one of the
|
||||
.Dv EAI_xxx
|
||||
values defined earlier and the return value points to a string describing
|
||||
the error.
|
||||
If the argument is not one of the
|
||||
.Dv EAI_xxx
|
||||
values, the function still returns a pointer to a string whose contents
|
||||
indicate an unknown error.
|
||||
.\"
|
||||
.Sh EXTENSION
|
||||
The implementation allows experimental numeric IPv6 address notation with
|
||||
scope identifier.
|
||||
By appending atmark and scope identifier to addresses, you can fill
|
||||
.Li sin6_scope_id
|
||||
field for addresses.
|
||||
This would make management of scoped address easier,
|
||||
and allows cut-and-paste input of scoped address.
|
||||
.Pp
|
||||
At this moment the code supports only link-local addresses with the format.
|
||||
Scope identifier is hardcoded to name of hardware interface associated
|
||||
with the link.
|
||||
.Po
|
||||
such as
|
||||
.Li ne0
|
||||
.Pc .
|
||||
Example would be like
|
||||
.Dq Li fe80::1@ne0 ,
|
||||
which means
|
||||
.Do
|
||||
.Li fe80::1
|
||||
on the link associated with
|
||||
.Li ne0
|
||||
interface
|
||||
.Dc .
|
||||
.Pp
|
||||
The implementation is still very experimental and non-standard.
|
||||
The current implementation assumes one-by-one relationship between
|
||||
interface and link, which is not necessarily true from the specification.
|
||||
.\"
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/resolv.conf -compact
|
||||
.It Pa /etc/hosts
|
||||
.It Pa /etc/host.conf
|
||||
.It Pa /etc/resolv.conf
|
||||
.El
|
||||
.\"
|
||||
.Sh DIAGNOSTICS
|
||||
Error return status from
|
||||
.Fn getaddrinfo
|
||||
is zero on success and non-zero on errors.
|
||||
Non-zero error codes are defined in
|
||||
.Li <netdb.h> ,
|
||||
and as follows:
|
||||
.Pp
|
||||
.Bl -tag -width EAI_ADDRFAMILY -compact
|
||||
.It Dv EAI_ADDRFAMILY
|
||||
address family for nodename not supported
|
||||
.It Dv EAI_AGAIN
|
||||
temporary failure in name resolution
|
||||
.It Dv EAI_BADFLAGS
|
||||
invalid value for ai_flags
|
||||
.It Dv EAI_FAIL
|
||||
non-recoverable failure in name resolution
|
||||
.It Dv EAI_FAMILY
|
||||
ai_family not supported
|
||||
.It Dv EAI_MEMORY
|
||||
memory allocation failure
|
||||
.It Dv EAI_NODATA
|
||||
no address associated with nodename
|
||||
.It Dv EAI_NONAME
|
||||
nodename nor servname provided, or not known
|
||||
.It Dv EAI_SERVICE
|
||||
servname not supported for ai_socktype
|
||||
.It Dv EAI_SOCKTYPE
|
||||
ai_socktype not supported
|
||||
.It Dv EAI_SYSTEM
|
||||
system error returned in errno
|
||||
.El
|
||||
.Pp
|
||||
If called with proper argument,
|
||||
.Fn gai_strerror
|
||||
returns a pointer to a string describing the given error code.
|
||||
If the argument is not one of the
|
||||
.Dv EAI_xxx
|
||||
values, the function still returns a pointer to a string whose contents
|
||||
indicate an unknown error.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr getnameinfo 3 ,
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr getservbyname 3 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr services 5 ,
|
||||
.Xr hostname 7 ,
|
||||
.Xr named 8 .
|
||||
.Pp
|
||||
.Rs
|
||||
.%A R. Gilligan
|
||||
.%A S. Thomson
|
||||
.%A J. Bound
|
||||
.%A W. Stevens
|
||||
.%T Basic Socket Interface Extensions for IPv6
|
||||
.%R RFC2553
|
||||
.%D March 1999
|
||||
.Re
|
||||
.\"
|
||||
.Sh HISTORY
|
||||
The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
|
||||
.\"
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn getaddrinfo
|
||||
function is defined IEEE POSIX 1003.1g draft specification,
|
||||
and documented in ``Basic Socket Interface Extensions for IPv6''
|
||||
.Pq RFC2533 .
|
||||
.\"
|
||||
.Sh BUGS
|
||||
The text was shamelessly copied from RFC2553.
|
1014
lib/libc/net/getaddrinfo.c
Normal file
1014
lib/libc/net/getaddrinfo.c
Normal file
File diff suppressed because it is too large
Load Diff
446
lib/libc/net/getipnodebyname.3
Normal file
446
lib/libc/net/getipnodebyname.3
Normal file
@ -0,0 +1,446 @@
|
||||
.\" Copyright (c) 1983, 1987, 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. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. 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.
|
||||
.\"
|
||||
.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
|
||||
.\" $Id: getipnodebyname.3,v 1.2 1999/09/13 16:04:51 itojun Exp $
|
||||
.\ $FreeBSD$
|
||||
.\"
|
||||
.Dd May 25, 1995
|
||||
.Dt GETIPNODEBYNAME 3
|
||||
.Os KAME
|
||||
.\"
|
||||
.Sh NAME
|
||||
.Nm getipnodebyname ,
|
||||
.Nm getipnodebyaddr ,
|
||||
.Nm freehostent
|
||||
.Nd nodename-to-address and address-to-nodename translation
|
||||
.\"
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/socket.h>
|
||||
.Fd #include <netdb.h>
|
||||
.Ft "struct hostent *"
|
||||
.Fn getipnodebyname "const char *name" "int af" "int flags" "int *error_num"
|
||||
.Ft "struct hostent *"
|
||||
.Fn getipnodebyaddr "const void *src" "size_t len" "int af" "int *error_num"
|
||||
.Ft void
|
||||
.Fn freehostent "struct hostent *ptr"
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Fn getipnodebyname
|
||||
and
|
||||
.Fn getipnodebyaddr
|
||||
functions are very similar to
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr gethostbyname2 3
|
||||
and
|
||||
.Xr gethostbyaddr 3 .
|
||||
The functions cover all the functionalities provided by the older ones,
|
||||
and provide better interface to programmers.
|
||||
The functions require additional arguments,
|
||||
.Ar af ,
|
||||
and
|
||||
.Ar flags ,
|
||||
for specifying address family and operation mode.
|
||||
The additional arguments allow programmer to get address for a nodename,
|
||||
for specific address family
|
||||
.Po
|
||||
such as
|
||||
.Dv AF_INET
|
||||
or
|
||||
.Dv AF_INET6
|
||||
.Pc .
|
||||
The functions also require an additional pointer argument,
|
||||
.Ar error_num
|
||||
to return the appropriate error code,
|
||||
to support thread safe error code returns.
|
||||
.Pp
|
||||
The type and usage of the return value,
|
||||
.Li "struct hostent"
|
||||
is described in
|
||||
.Xr gethostbyname 3 .
|
||||
.Pp
|
||||
For
|
||||
.Fn getipnodebyname ,
|
||||
the
|
||||
.Ar name
|
||||
argument can be either a node name or a numeric address
|
||||
string
|
||||
.Po
|
||||
i.e., a dotted-decimal IPv4 address or an IPv6 hex address
|
||||
.Pc .
|
||||
The
|
||||
.Ar af
|
||||
argument specifies the address family, either
|
||||
.Dv AF_INET
|
||||
or
|
||||
.Dv AF_INET6 .
|
||||
The
|
||||
.Ar flags
|
||||
argument specifies the types of addresses that are searched for,
|
||||
and the types of addresses that are returned.
|
||||
We note that a special flags value of
|
||||
.Dv AI_DEFAULT
|
||||
.Pq defined below
|
||||
should handle most applications.
|
||||
That is, porting simple applications to use IPv6 replaces the call
|
||||
.Bd -literal -offset
|
||||
hptr = gethostbyname(name);
|
||||
.Ed
|
||||
.Pp
|
||||
with
|
||||
.Bd -literal -offset
|
||||
hptr = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num);
|
||||
.Ed
|
||||
.Pp
|
||||
Applications desiring finer control over the types of addresses
|
||||
searched for and returned, can specify other combinations of the
|
||||
.Ar flags
|
||||
argument.
|
||||
.Pp
|
||||
A
|
||||
.Ar flags
|
||||
of
|
||||
.Li 0
|
||||
implies a strict interpretation of the
|
||||
.Ar af
|
||||
argument:
|
||||
.Bl -bullet
|
||||
.It
|
||||
If
|
||||
.Ar flags
|
||||
is 0 and
|
||||
.Ar af
|
||||
is
|
||||
.Dv AF_INET ,
|
||||
then the caller wants only IPv4 addresses.
|
||||
A query is made for
|
||||
.Li A
|
||||
records.
|
||||
If successful, the IPv4 addresses are returned and the
|
||||
.Li h_length
|
||||
member of the
|
||||
.Li hostent
|
||||
structure will be 4, else the function returns a
|
||||
.Dv NULL
|
||||
pointer.
|
||||
.It
|
||||
If
|
||||
.Ar flags
|
||||
is 0 and if
|
||||
.Ar af
|
||||
is
|
||||
.Li AF_INET6 ,
|
||||
then the caller wants only IPv6 addresses.
|
||||
A query is made for
|
||||
.Li AAAA
|
||||
records.
|
||||
If successful, the IPv6 addresses are returned and the
|
||||
.Li h_length
|
||||
member of the
|
||||
.Li hostent
|
||||
structure will be 16, else the function returns a
|
||||
.Dv NULL
|
||||
pointer.
|
||||
.El
|
||||
.Pp
|
||||
Other constants can be logically-ORed into the
|
||||
.Ar flags
|
||||
argument, to modify the behavior of the function.
|
||||
.Bl -bullet
|
||||
.It
|
||||
If the
|
||||
.Dv AI_V4MAPPED
|
||||
flag is specified along with an
|
||||
.Ar af
|
||||
of
|
||||
.Dv AF_INET6 ,
|
||||
then the caller will accept IPv4-mapped IPv6 addresses.
|
||||
That is, if no
|
||||
.Li AAAA
|
||||
records are found then a query is made for
|
||||
.Li A
|
||||
records and any found are returned as IPv4-mapped IPv6 addresses
|
||||
.Po
|
||||
.Li h_length
|
||||
will be 16
|
||||
.Pc .
|
||||
The
|
||||
.Dv AI_V4MAPPED
|
||||
flag is ignored unless
|
||||
.Ar af
|
||||
equals
|
||||
.Dv AF_INET6 .
|
||||
.It
|
||||
The
|
||||
.Dv AI_V4MAPPED_CFG
|
||||
flag is exact same as the
|
||||
.Dv AI_V4MAPPED
|
||||
flag only if the kernel supports IPv4-mapped IPv6 address.
|
||||
.It
|
||||
If the
|
||||
.Dv AI_ALL
|
||||
flag is used in conjunction with the
|
||||
.Dv AI_V4MAPPED
|
||||
flag, and only used with the IPv6 address family.
|
||||
When
|
||||
.Dv AI_ALL
|
||||
is logically or'd with
|
||||
.Dv AI_V4MAPPED
|
||||
flag then the caller wants all addresses: IPv6 and IPv4-mapped IPv6.
|
||||
A query is first made for
|
||||
.Li AAAA
|
||||
records and if successful, the
|
||||
IPv6 addresses are returned. Another query is then made for
|
||||
.Li A
|
||||
records and any found are returned as IPv4-mapped IPv6 addresses.
|
||||
.Li h_length
|
||||
will be 16. Only if both queries fail does the function
|
||||
return a
|
||||
.Dv NULL
|
||||
pointer. This flag is ignored unless af equals
|
||||
AF_INET6. If both
|
||||
.Dv AI_ALL
|
||||
and
|
||||
.Dv AI_V4MAPPED
|
||||
are specified,
|
||||
.Dv AI_ALL
|
||||
takes precedence.
|
||||
.It
|
||||
The
|
||||
.Dv AI_ADDRCONFIG
|
||||
flag specifies that a query for
|
||||
.Li AAAA
|
||||
records
|
||||
should occur only if the node has at least one IPv6 source
|
||||
address configured and a query for
|
||||
.Li A
|
||||
records should occur only if the node has at least one IPv4 source address
|
||||
configured.
|
||||
.Pp
|
||||
For example, if the node has no IPv6 source addresses configured,
|
||||
and
|
||||
.Ar af
|
||||
equals AF_INET6, and the node name being looked up has both
|
||||
.Li AAAA
|
||||
and
|
||||
.Li A
|
||||
records, then:
|
||||
(a) if only
|
||||
.Dv AI_ADDRCONFIG
|
||||
is
|
||||
specified, the function returns a
|
||||
.Dv NULL
|
||||
pointer;
|
||||
(b) if
|
||||
.Dv AI_ADDRCONFIG
|
||||
|
|
||||
.Dv AI_V4MAPPED
|
||||
is specified, the
|
||||
.Li A
|
||||
records are returned as IPv4-mapped IPv6 addresses;
|
||||
.El
|
||||
.Pp
|
||||
The special flags value of
|
||||
.Dv AI_DEFAULT
|
||||
is defined as
|
||||
.Bd -literal -offset
|
||||
#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
|
||||
.Ed
|
||||
.Pp
|
||||
We noted that the
|
||||
.Fn getipnodebyname
|
||||
function must allow the
|
||||
.Ar name
|
||||
argument to be either a node name or a literal address string
|
||||
.Po
|
||||
i.e., a dotted-decimal IPv4 address or an IPv6 hex address
|
||||
.Pc .
|
||||
This saves applications from having to call
|
||||
.Xr inet_pton 3
|
||||
to handle literal address strings.
|
||||
When the
|
||||
.Ar name
|
||||
argument is a literal address string,
|
||||
the
|
||||
.Ar flags
|
||||
argument is always ignored.
|
||||
.Pp
|
||||
There are four scenarios based on the type of literal address string
|
||||
and the value of the
|
||||
.Ar af
|
||||
argument.
|
||||
The two simple cases are when
|
||||
.Ar name
|
||||
is a dotted-decimal IPv4 address and
|
||||
.Ar af
|
||||
equals
|
||||
.Dv AF_INET ,
|
||||
or when
|
||||
.Ar name
|
||||
is an IPv6 hex address and
|
||||
.Ar af
|
||||
equals
|
||||
.Dv AF_INET6 .
|
||||
The members of the
|
||||
returned hostent structure are:
|
||||
.Li h_name
|
||||
points to a copy of the
|
||||
.Ar name
|
||||
argument,
|
||||
.Li h_aliases
|
||||
is a
|
||||
.Dv NULL
|
||||
pointer,
|
||||
.Li h_addrtype
|
||||
is a copy of the
|
||||
.Ar af
|
||||
argument,
|
||||
.Li h_length
|
||||
is either 4
|
||||
.Po
|
||||
for
|
||||
.Dv AF_INET
|
||||
.Pc
|
||||
or 16
|
||||
.Po
|
||||
for
|
||||
.Dv AF_INET6
|
||||
.Pc ,
|
||||
.Li h_addr_list[0]
|
||||
is a pointer to the 4-byte or 16-byte binary address,
|
||||
and
|
||||
.Li h_addr_list[1]
|
||||
is a
|
||||
.Dv NULL
|
||||
pointer.
|
||||
.Pp
|
||||
When
|
||||
.Ar name
|
||||
is a dotted-decimal IPv4 address and
|
||||
.Ar af
|
||||
equals
|
||||
.Dv AF_INET6 ,
|
||||
and
|
||||
.Dv AI_V4MAPPED
|
||||
is specified,
|
||||
an IPv4-mapped IPv6 address is returned:
|
||||
.Li h_name
|
||||
points to an IPv6 hex address containing the IPv4-mapped IPv6 address,
|
||||
.Li h_aliases
|
||||
is a
|
||||
.Dv NULL
|
||||
pointer,
|
||||
.Li h_addrtype
|
||||
is
|
||||
.Dv AF_INET6 ,
|
||||
.Li h_length
|
||||
is 16,
|
||||
.Li h_addr_list[0]
|
||||
is a pointer to the 16-byte binary address, and
|
||||
.Li h_addr_list[1]
|
||||
is a
|
||||
.Dv NULL
|
||||
pointer.
|
||||
.Pp
|
||||
It is an error when
|
||||
.Ar name
|
||||
is an IPv6 hex address and
|
||||
.Ar af
|
||||
equals
|
||||
.Dv AF_INET .
|
||||
The function's return value is a
|
||||
.Dv NULL
|
||||
pointer and the value pointed to by
|
||||
.Ar error_num
|
||||
equals
|
||||
.Dv HOST_NOT_FOUND .
|
||||
.Pp
|
||||
.Fn getipnodebyaddr
|
||||
takes almost the same argument as
|
||||
.Xr gethostbyaddr 3 ,
|
||||
but adds a pointer to return an error number.
|
||||
Additionally it takes care of IPv4-mapped IPv6 addresses,
|
||||
and IPv4-compatible IPv6 addresses.
|
||||
.Pp
|
||||
.Fn getipnodebyname
|
||||
and
|
||||
.Fn getipnodebyaddr
|
||||
dynamically allocate the structure to be returned to the caller.
|
||||
.Fn freehostent
|
||||
reclaims memory region allocated and returned by
|
||||
.Fn getipnodebyname
|
||||
or
|
||||
.Fn getipnodebyaddr .
|
||||
.\"
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/resolv.conf -compact
|
||||
.It Pa /etc/hosts
|
||||
.It Pa /etc/host.conf
|
||||
.It Pa /etc/resolv.conf
|
||||
.El
|
||||
.\"
|
||||
.Sh DIAGNOSTICS
|
||||
.Nm getipnodebyname
|
||||
and
|
||||
.Nm getipnodebyaddr
|
||||
returns
|
||||
.Dv NULL
|
||||
on errors.
|
||||
The integer values pointed to by
|
||||
.Ar error_num
|
||||
may then be checked to see whether this is a temporary failure
|
||||
or an invalid or unknown host.
|
||||
The meanings of each error code are described in
|
||||
.Xr gethostbyname 3 .
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr gethostbyaddr 3 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr services 5 ,
|
||||
.Xr hostname 7 ,
|
||||
.Xr named 8
|
||||
.Pp
|
||||
R. Gilligan, S. Thomson, J. Bound, and W. Stevens,
|
||||
``Basic Socket Interface Extensions for IPv6,'' RFC2553, March 1999.
|
||||
.\"
|
||||
.Sh HISTORY
|
||||
The implementation first appeared in KAME advanced networking kit.
|
||||
.\"
|
||||
.Sh STANDARDS
|
||||
.Fn getipnodebyname
|
||||
and
|
||||
.Fn getipnodebyaddr
|
||||
are documented in ``Basic Socket Interface Extensions for IPv6''
|
||||
.Pq RFC2553 .
|
||||
.\"
|
||||
.Sh BUGS
|
||||
The text was shamelessly copied from RFC2553.
|
232
lib/libc/net/getnameinfo.3
Normal file
232
lib/libc/net/getnameinfo.3
Normal file
@ -0,0 +1,232 @@
|
||||
.\" Copyright (c) 1983, 1987, 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. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. 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.
|
||||
.\"
|
||||
.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
|
||||
.\" $Id: getnameinfo.3,v 1.2 1999/10/07 04:46:27 itojun Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 25, 1995
|
||||
.Dt GETNAMEINFO 3
|
||||
.Os KAME
|
||||
.\"
|
||||
.Sh NAME
|
||||
.Nm getnameinfo
|
||||
.Nd address-to-nodename translation in protocol-independent manner
|
||||
.\"
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/socket.h>
|
||||
.Fd #include <netdb.h>
|
||||
.Ft int
|
||||
.Fn getnameinfo "const struct sockaddr *sa" "socklen_t salen" \
|
||||
"char *host" "size_t hostlen" "char *serv" "size_t servlen" "int flags"
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn getnameinfo
|
||||
function is defined for protocol-independent address-to-nodename translation.
|
||||
Its functionality is a reverse conversion of
|
||||
.Xr getaddrinfo 3 ,
|
||||
and implements similar functionality with
|
||||
.Xr gethostbyaddr 3 and
|
||||
.Xr getservbyport 3
|
||||
in more sophisticated manner.
|
||||
.Pp
|
||||
This function looks up an IP address and port number provided by the
|
||||
caller in the DNS and system-specific database, and returns text
|
||||
strings for both in buffers provided by the caller.
|
||||
The function indicates successful completion by a zero return value;
|
||||
a non-zero return value indicates failure.
|
||||
.Pp
|
||||
The first argument,
|
||||
.Fa sa ,
|
||||
points to either a
|
||||
.Fa sockaddr_in
|
||||
structure (for IPv4) or a
|
||||
.Fa sockaddr_in6
|
||||
structure (for IPv6) that holds the IP address and port number.
|
||||
The
|
||||
.Fa salen
|
||||
argument gives the length of the
|
||||
.Fa sockaddr_in
|
||||
or
|
||||
.Fa sockaddr_in6
|
||||
structure.
|
||||
.Pp
|
||||
The function returns the nodename associated with the IP address in
|
||||
the buffer pointed to by the
|
||||
.Fa host
|
||||
argument.
|
||||
The caller provides the size of this buffer via the
|
||||
.Fa hostlen
|
||||
argument.
|
||||
The service name associated with the port number is returned in the buffer
|
||||
pointed to by
|
||||
.Fa serv ,
|
||||
and the
|
||||
.Fa servlen
|
||||
argument gives the length of this buffer.
|
||||
The caller specifies not to return either string by providing a zero
|
||||
value for the
|
||||
.Fa hostlen
|
||||
or
|
||||
.Fa servlen
|
||||
arguments.
|
||||
Otherwise, the caller must provide buffers large enough to hold the
|
||||
nodename and the service name, including the terminating null characters.
|
||||
.Pp
|
||||
Unfortunately most systems do not provide constants that specify the
|
||||
maximum size of either a fully-qualified domain name or a service name.
|
||||
Therefore to aid the application in allocating buffers for these two
|
||||
returned strings the following constants are defined in
|
||||
.Li <netdb.h> :
|
||||
.Bd -literal -offset
|
||||
#define NI_MAXHOST 1025
|
||||
#define NI_MAXSERV 32
|
||||
.Ed
|
||||
.Pp
|
||||
The first value is actually defined as the constant
|
||||
.Dv MAXDNAME
|
||||
in recent versions of BIND's
|
||||
.Li <arpa/nameser.h>
|
||||
header
|
||||
.Po
|
||||
older versions of BIND define this constant to be 256
|
||||
.Pc
|
||||
and the second is a guess based on the services listed in the current
|
||||
Assigned Numbers RFC.
|
||||
.Pp
|
||||
The final argument is a
|
||||
.Fa flag
|
||||
that changes the default actions of this function.
|
||||
By default the fully-qualified domain name (FQDN) for the host is
|
||||
looked up in the DNS and returned.
|
||||
If the flag bit
|
||||
.Dv NI_NOFQDN
|
||||
is set, only the nodename portion of the FQDN is returned for local hosts.
|
||||
.Pp
|
||||
If the
|
||||
.Fa flag
|
||||
bit
|
||||
.Dv NI_NUMERICHOST
|
||||
is set, or if the host's name cannot be located in the DNS,
|
||||
the numeric form of the host's address is returned instead of its name
|
||||
.Po
|
||||
e.g., by calling
|
||||
.Fn inet_ntop
|
||||
instead of
|
||||
.Fn getnodebyaddr
|
||||
.Pc .
|
||||
If the
|
||||
.Fa flag
|
||||
bit
|
||||
.Dv NI_NAMEREQD
|
||||
is set, an error is returned if the host's name cannot be located in the DNS.
|
||||
.Pp
|
||||
If the flag bit
|
||||
.Dv NI_NUMERICSERV
|
||||
is set, the numeric form of the service address is returned
|
||||
.Pq e.g., its port number
|
||||
instead of its name.
|
||||
The two
|
||||
.Dv NI_NUMERICxxx
|
||||
flags are required to support the
|
||||
.Li "-n"
|
||||
flag that many commands provide.
|
||||
.Pp
|
||||
A fifth flag bit,
|
||||
.Dv NI_DGRAM ,
|
||||
specifies that the service is a datagram service, and causes
|
||||
.Fn getservbyport
|
||||
to be called with a second argument of "udp" instead of its default of "tcp".
|
||||
This is required for the few ports (512-514)
|
||||
that have different services for UDP and TCP.
|
||||
.Pp
|
||||
These
|
||||
.Dv NI_xxx
|
||||
flags are defined in
|
||||
.Li <netdb.h> .
|
||||
.\"
|
||||
.Sh EXTENSION
|
||||
The implementation allows experimental numeric IPv6 address notation with
|
||||
scope identifier.
|
||||
IPv6 link-local address will appear as string like
|
||||
.Dq Li fe80::1@ne0 ,
|
||||
if
|
||||
.Dv NI_WITHSCOPEID
|
||||
bit is enabled in
|
||||
.Ar flags
|
||||
argument.
|
||||
Refer to
|
||||
.Xr getaddrinfo 3
|
||||
for the notation.
|
||||
.\"
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/resolv.conf -compact
|
||||
.It Pa /etc/hosts
|
||||
.It Pa /etc/host.conf
|
||||
.It Pa /etc/resolv.conf
|
||||
.El
|
||||
.\"
|
||||
.Sh DIAGNOSTICS
|
||||
The function indicates successful completion by a zero return value;
|
||||
a non-zero return value indicates failure.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr getaddrinfo 3 ,
|
||||
.Xr gethostbyaddr 3 ,
|
||||
.Xr getservbyport 3 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr services 5 ,
|
||||
.Xr hostname 7 ,
|
||||
.Xr named 8
|
||||
.Pp
|
||||
.Rs
|
||||
.%A R. Gilligan
|
||||
.%A S. Thomson
|
||||
.%A J. Bound
|
||||
.%A W. Stevens
|
||||
.%T Basic Socket Interface Extensions for IPv6
|
||||
.%R RFC2553
|
||||
.%D March 1999
|
||||
.Re
|
||||
.\"
|
||||
.Sh HISTORY
|
||||
The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
|
||||
.\"
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn getaddrinfo
|
||||
function is defined IEEE POSIX 1003.1g draft specification,
|
||||
and documented in ``Basic Socket Interface Extensions for IPv6''
|
||||
.Pq RFC2533 .
|
||||
.\"
|
||||
.Sh BUGS
|
||||
The text was shamelessly copied from RFC2553.
|
228
lib/libc/net/getnameinfo.c
Normal file
228
lib/libc/net/getnameinfo.c
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Issues to be discussed:
|
||||
* - Thread safe-ness must be checked
|
||||
* - Return values. There seems to be no standard for return value (RFC2553)
|
||||
* but INRIA implementation returns EAI_xxx defined for getaddrinfo().
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define SUCCESS 0
|
||||
#define ANY 0
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
static struct afd {
|
||||
int a_af;
|
||||
int a_addrlen;
|
||||
int a_socklen;
|
||||
int a_off;
|
||||
} afdl [] = {
|
||||
#ifdef INET6
|
||||
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
|
||||
offsetof(struct sockaddr_in6, sin6_addr)},
|
||||
#endif
|
||||
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
|
||||
offsetof(struct sockaddr_in, sin_addr)},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
struct sockinet {
|
||||
u_char si_len;
|
||||
u_char si_family;
|
||||
u_short si_port;
|
||||
};
|
||||
|
||||
#define ENI_NOSOCKET 0
|
||||
#define ENI_NOSERVHOST 1
|
||||
#define ENI_NOHOSTNAME 2
|
||||
#define ENI_MEMORY 3
|
||||
#define ENI_SYSTEM 4
|
||||
#define ENI_FAMILY 5
|
||||
#define ENI_SALEN 6
|
||||
|
||||
int
|
||||
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
const struct sockaddr *sa;
|
||||
size_t salen;
|
||||
char *host;
|
||||
size_t hostlen;
|
||||
char *serv;
|
||||
size_t servlen;
|
||||
int flags;
|
||||
{
|
||||
struct afd *afd;
|
||||
struct servent *sp;
|
||||
struct hostent *hp;
|
||||
u_short port;
|
||||
int family, i;
|
||||
char *addr, *p;
|
||||
u_long v4a;
|
||||
int h_error;
|
||||
char numserv[512];
|
||||
char numaddr[512];
|
||||
int noserv = 0;
|
||||
|
||||
if (sa == NULL)
|
||||
return ENI_NOSOCKET;
|
||||
|
||||
if (sa->sa_len != salen)
|
||||
return ENI_SALEN;
|
||||
|
||||
family = sa->sa_family;
|
||||
for (i = 0; afdl[i].a_af; i++)
|
||||
if (afdl[i].a_af == family) {
|
||||
afd = &afdl[i];
|
||||
goto found;
|
||||
}
|
||||
return ENI_FAMILY;
|
||||
|
||||
found:
|
||||
if (salen != afd->a_socklen)
|
||||
return ENI_SALEN;
|
||||
|
||||
port = ((struct sockinet *)sa)->si_port; /* network byte order */
|
||||
addr = (char *)sa + afd->a_off;
|
||||
|
||||
if (serv == NULL || servlen == 0) {
|
||||
noserv = 1;
|
||||
} else {
|
||||
if (flags & NI_NUMERICSERV)
|
||||
sp = NULL;
|
||||
else {
|
||||
sp = getservbyport(port,
|
||||
(flags & NI_DGRAM) ? "udp" : "tcp");
|
||||
}
|
||||
if (sp) {
|
||||
if (strlen(sp->s_name) > servlen)
|
||||
return ENI_MEMORY;
|
||||
strcpy(serv, sp->s_name);
|
||||
} else {
|
||||
snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
|
||||
if (strlen(numserv) > servlen)
|
||||
return ENI_MEMORY;
|
||||
strcpy(serv, numserv);
|
||||
}
|
||||
}
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
v4a = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
|
||||
if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
|
||||
flags |= NI_NUMERICHOST;
|
||||
v4a >>= IN_CLASSA_NSHIFT;
|
||||
if (v4a == 0 || v4a == IN_LOOPBACKNET)
|
||||
flags |= NI_NUMERICHOST;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
sin6 = (struct sockaddr_in6 *)sa;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
|
||||
IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
|
||||
flags |= NI_NUMERICHOST;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (host == NULL || hostlen == 0) {
|
||||
if (noserv == 1)
|
||||
return ENI_NOSERVHOST;
|
||||
} else if (flags & NI_NUMERICHOST) {
|
||||
/* NUMERICHOST and NAMEREQD conflicts with each other */
|
||||
if (flags & NI_NAMEREQD)
|
||||
return ENI_NOHOSTNAME;
|
||||
if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
|
||||
== NULL)
|
||||
return ENI_SYSTEM;
|
||||
if (strlen(numaddr) > hostlen)
|
||||
return ENI_MEMORY;
|
||||
strcpy(host, numaddr);
|
||||
#ifdef INET6
|
||||
if (afd->a_af == AF_INET6 &&
|
||||
(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr) ||
|
||||
IN6_IS_ADDR_MULTICAST((struct in6_addr *)addr)) &&
|
||||
((struct sockaddr_in6 *)sa)->sin6_scope_id) {
|
||||
if (flags & NI_WITHSCOPEID) {
|
||||
char *ep = strchr(host, '\0');
|
||||
unsigned int ifindex =
|
||||
((struct sockaddr_in6 *)sa)->sin6_scope_id;
|
||||
char ifname[IF_NAMESIZE * 2 /* for safety */];
|
||||
|
||||
if ((if_indextoname(ifindex, ifname)) == NULL)
|
||||
return ENI_SYSTEM;
|
||||
if (strlen(host) + 1 /* SCOPE_DELIMITER */
|
||||
+ strlen(ifname) > hostlen)
|
||||
return ENI_MEMORY;
|
||||
*ep = SCOPE_DELIMITER;
|
||||
strcpy(ep + 1, ifname);
|
||||
}
|
||||
}
|
||||
#endif /* INET6 */
|
||||
} else {
|
||||
hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
|
||||
if (hp) {
|
||||
if (flags & NI_NOFQDN) {
|
||||
p = strchr(hp->h_name, '.');
|
||||
if (p) *p = '\0';
|
||||
}
|
||||
if (strlen(hp->h_name) > hostlen) {
|
||||
freehostent(hp);
|
||||
return ENI_MEMORY;
|
||||
}
|
||||
strcpy(host, hp->h_name);
|
||||
freehostent(hp);
|
||||
} else {
|
||||
if (flags & NI_NAMEREQD)
|
||||
return ENI_NOHOSTNAME;
|
||||
if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
|
||||
== NULL)
|
||||
return ENI_NOHOSTNAME;
|
||||
if (strlen(numaddr) > hostlen)
|
||||
return ENI_MEMORY;
|
||||
strcpy(host, numaddr);
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
1260
lib/libc/net/name6.c
Normal file
1260
lib/libc/net/name6.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -112,6 +112,9 @@ struct __res_state _res
|
||||
# endif
|
||||
;
|
||||
|
||||
#ifdef INET6
|
||||
struct __res_state_ext _res_ext;
|
||||
#endif /* INET6 */
|
||||
|
||||
/*
|
||||
* Set up default settings. If the configuration file exist, the values
|
||||
@ -314,6 +317,9 @@ res_init()
|
||||
#ifdef RESOLVSORT
|
||||
if (MATCH(buf, "sortlist")) {
|
||||
struct in_addr a;
|
||||
#ifdef INET6
|
||||
struct in6_addr a6;
|
||||
#endif /* INET6 */
|
||||
|
||||
cp = buf + sizeof("sortlist") - 1;
|
||||
while (nsort < MAXRESOLVSORT) {
|
||||
@ -347,8 +353,61 @@ res_init()
|
||||
_res.sort_list[nsort].mask =
|
||||
net_mask(_res.sort_list[nsort].addr);
|
||||
}
|
||||
#ifdef INET6
|
||||
_res_ext.sort_list[nsort].af = AF_INET;
|
||||
_res_ext.sort_list[nsort].addr.ina =
|
||||
_res.sort_list[nsort].addr;
|
||||
_res_ext.sort_list[nsort].mask.ina.s_addr =
|
||||
_res.sort_list[nsort].mask;
|
||||
#endif /* INET6 */
|
||||
nsort++;
|
||||
}
|
||||
#ifdef INET6
|
||||
else if (inet_pton(AF_INET6, net, &a6) == 1) {
|
||||
int m, i;
|
||||
u_char *u;
|
||||
|
||||
_res_ext.sort_list[nsort].af = AF_INET6;
|
||||
_res_ext.sort_list[nsort].addr.in6a = a6;
|
||||
u = (u_char *)&_res_ext.sort_list[nsort].mask.in6a;
|
||||
*cp++ = n;
|
||||
net = cp;
|
||||
while (*cp && *cp != ';' &&
|
||||
isascii(*cp) && !isspace(*cp))
|
||||
cp++;
|
||||
m = n;
|
||||
n = *cp;
|
||||
*cp = 0;
|
||||
switch (m) {
|
||||
case '/':
|
||||
m = atoi(net);
|
||||
break;
|
||||
case '&':
|
||||
if (inet_pton(AF_INET6, net, u) == 1) {
|
||||
m = -1;
|
||||
break;
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
m = sizeof(struct in6_addr) * NBBY;
|
||||
break;
|
||||
}
|
||||
if (m >= 0) {
|
||||
for (i = 0; i < sizeof(struct in6_addr); i++) {
|
||||
if (m <= 0) {
|
||||
*u = 0;
|
||||
} else {
|
||||
m -= NBBY;
|
||||
*u = (u_char)~0;
|
||||
if (m < 0)
|
||||
*u <<= -m;
|
||||
}
|
||||
u++;
|
||||
}
|
||||
}
|
||||
nsort++;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
*cp = n;
|
||||
}
|
||||
continue;
|
||||
|
@ -50,11 +50,13 @@ SUBDIR= adjkerntz \
|
||||
nologin \
|
||||
nos-tun \
|
||||
ping \
|
||||
ping6 \
|
||||
quotacheck \
|
||||
reboot \
|
||||
restore \
|
||||
route \
|
||||
routed \
|
||||
rtsol \
|
||||
savecore \
|
||||
shutdown \
|
||||
slattach \
|
||||
|
25
sbin/ping6/Makefile
Normal file
25
sbin/ping6/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# Copyright (c) 1996 WIDE Project. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modifications, are permitted provided that the above copyright notice
|
||||
# and this paragraph are duplicated in all such forms and that any
|
||||
# documentation, advertising materials, and other materials related to
|
||||
# such distribution and use acknowledge that the software was developed
|
||||
# by the WIDE Project, Japan. The name of the Project may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
|
||||
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE.
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ping6
|
||||
MAN8= ping6.8
|
||||
BINMODE = 4555
|
||||
COPTS+= -Wall -Wmissing-prototypes
|
||||
.if ${MACHINE_ARCH} == "alpha"
|
||||
COPTS+= -fno-builtin # GCC's builtin memcpy doesn't do unaligned copies
|
||||
.endif
|
||||
CFLAGS+= -DINET6
|
||||
|
||||
.include <bsd.prog.mk>
|
332
sbin/ping6/ping6.8
Normal file
332
sbin/ping6/ping6.8
Normal file
@ -0,0 +1,332 @@
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" 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 project 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 PROJECT 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 PROJECT 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.
|
||||
.\"
|
||||
.\" $Id: ping6.8,v 1.4 1999/10/07 05:29:03 itojun Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 17, 1998
|
||||
.Dt PING6 8
|
||||
.Os KAME
|
||||
.Sh NAME
|
||||
.Nm ping6
|
||||
.Nd send
|
||||
.Tn ICMPv6 ECHO_REQUEST
|
||||
packets to network hosts
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl AdEfnqRrvw
|
||||
.Op Fl a Ar addrtype
|
||||
.Op Fl b Ar bufsiz
|
||||
.Op Fl c Ar count
|
||||
.Op Fl h Ar hoplimit
|
||||
.Op Fl I Ar interface
|
||||
.Op Fl i Ar wait
|
||||
.Op Fl l Ar preload
|
||||
.Op Fl p Ar pattern
|
||||
.Op Fl s Ar packetsize
|
||||
.Ar host
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -width Ds
|
||||
.It Fl A
|
||||
Enables transport-mode IPsec authentication header. (experimental)
|
||||
.It Fl a Ar addrtype
|
||||
Generate ICMPv6 Node Information Node Addresses query, rather than echo-request.
|
||||
.Ar addrtype
|
||||
must be a string constructed of the following charaters.
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Ic a
|
||||
requires all the responder's unicast addresses. If the charater is ommited,
|
||||
only those addresses which belong to the interface which has the
|
||||
responder's address are required.
|
||||
.It Ic g
|
||||
requires responder's global-scope addresses.
|
||||
.It Ic s
|
||||
requires responder's site-local addresses.
|
||||
.It Ic l
|
||||
requires responder's link-local addresses.
|
||||
.It Ic A
|
||||
requires responder's anycast addresses. Without this character, the responder
|
||||
will return unicast addresses only. With this character, the responder
|
||||
will return anycast addresses only.
|
||||
Note that the specification does not specify how to get responder's
|
||||
anycast addresses. This is an experimental option.
|
||||
.El
|
||||
.It Fl b Ar bufsiz
|
||||
Set socket buffer size.
|
||||
.It Fl c Ar count
|
||||
Stop after sending
|
||||
.Pq and receiving
|
||||
.Ar count
|
||||
.Tn ECHO_RESPONSE
|
||||
packets.
|
||||
.It Fl d
|
||||
Set the
|
||||
.Dv SO_DEBUG
|
||||
option on the socket being used.
|
||||
.It Fl E
|
||||
Enables transport-mode IPsec encapsulated security payload. (experimental)
|
||||
.It Fl f
|
||||
Flood ping.
|
||||
Outputs packets as fast as they come back or one hundred times per second,
|
||||
whichever is more.
|
||||
For every
|
||||
.Tn ECHO_REQUEST
|
||||
sent a period
|
||||
.Dq \&.
|
||||
is printed, while for every
|
||||
.Tn ECHO_REPLY
|
||||
received a backspace is printed.
|
||||
This provides a rapid display of how many packets are being dropped.
|
||||
Only the super-user may use this option.
|
||||
.Bf -emphasis
|
||||
This can be very hard on a network and should be used with caution.
|
||||
.Ef
|
||||
.It Fl h Ar hoplimit
|
||||
Set the IPv6 hoplimit.
|
||||
.It Fl I Ar interface
|
||||
Source packets with the given interface address.
|
||||
This flag applies if the ping destination is a multicast address,
|
||||
or link-local/site-local unicast address.
|
||||
.It Fl i Ar wait
|
||||
Wait
|
||||
.Ar wait
|
||||
seconds
|
||||
.Em between sending each packet .
|
||||
The default is to wait for one second between each packet.
|
||||
This option is incompatible with the
|
||||
.Fl f
|
||||
option.
|
||||
.It Fl l Ar preload
|
||||
If
|
||||
.Ar preload
|
||||
is specified,
|
||||
.Nm ping
|
||||
sends that many packets as fast as possible before falling into its normal
|
||||
mode of behavior.
|
||||
Only the super-user may use this option.
|
||||
.It Fl n
|
||||
Numeric output only.
|
||||
No attempt will be made to lookup symbolic names for host addresses.
|
||||
.It Fl p Ar pattern
|
||||
You may specify up to 16
|
||||
.Dq pad
|
||||
bytes to fill out the packet you send.
|
||||
This is useful for diagnosing data-dependent problems in a network.
|
||||
For example,
|
||||
.Dq Li \-p ff
|
||||
will cause the sent packet to be filled with all
|
||||
ones.
|
||||
.Fl Q
|
||||
flag,
|
||||
.Nm
|
||||
prints out any ICMP error messages caused by its own ECHO_REQUEST
|
||||
messages.
|
||||
.It Fl q
|
||||
Quiet output.
|
||||
Nothing is displayed except the summary lines at startup time and
|
||||
when finished.
|
||||
.It Fl R
|
||||
Record route.
|
||||
Includes the
|
||||
.Tn RECORD_ROUTE
|
||||
option in the
|
||||
.Tn ECHO_REQUEST
|
||||
packet and displays
|
||||
the route buffer on returned packets.
|
||||
Note that the IP header is only large enough for nine such routes;
|
||||
the
|
||||
.Xr traceroute 8
|
||||
command is usually better at determining the route packets take to a
|
||||
particular destination.
|
||||
Many hosts ignore or discard the
|
||||
.Tn RECORD_ROUTE
|
||||
option.
|
||||
.It Fl r
|
||||
Bypass the normal routing tables and send directly to a host on an attached
|
||||
network.
|
||||
If the host is not on a directly-attached network, an error is returned.
|
||||
This option can be used to ping a local host through an interface
|
||||
that has no route through it
|
||||
.Po
|
||||
e.g., after the interface was dropped by
|
||||
.Xr routed 8
|
||||
.Pc .
|
||||
.It Fl s Ar packetsize
|
||||
Specifies the number of data bytes to be sent.
|
||||
The default is 56, which translates into 64
|
||||
.Tn ICMP
|
||||
data bytes when combined
|
||||
with the 8 bytes of
|
||||
.Tn ICMP
|
||||
header data.
|
||||
You may need to specify
|
||||
.Fl b
|
||||
as well to extend socket buffer size.
|
||||
.It Fl v
|
||||
Verbose output.
|
||||
.Tn ICMP
|
||||
packets other than
|
||||
.Tn ECHO_RESPONSE
|
||||
that are received are listed.
|
||||
.It Fl w
|
||||
Generate ICMPv6 Node Information FQDN query, rather than echo-request.
|
||||
.Fl s
|
||||
has no effect if
|
||||
.Fl w
|
||||
is specified.
|
||||
.It Fl W
|
||||
Same as
|
||||
.Fl w .
|
||||
This option was remained for backward compatibility.
|
||||
.Fl s
|
||||
has no effect if
|
||||
.Fl w
|
||||
is specified.
|
||||
.El
|
||||
.Pp
|
||||
When using
|
||||
.Nm
|
||||
for fault isolation, it should first be run on the local host, to verify
|
||||
that the local network interface is up and running.
|
||||
Then, hosts and gateways further and further away should be
|
||||
.Dq pinged .
|
||||
Round-trip times and packet loss statistics are computed.
|
||||
If duplicate packets are received, they are not included in the packet
|
||||
loss calculation, although the round trip time of these packets is used
|
||||
in calculating the round-trip time statistics.
|
||||
When the specified number of packets have been sent
|
||||
.Pq and received
|
||||
or if the program is terminated with a
|
||||
.Dv SIGINT ,
|
||||
a brief summary is displayed, showing the number of packets sent and
|
||||
received, and the minimum, maximum, mean, and standard deviation of
|
||||
the round-trip times.
|
||||
.Pp
|
||||
This program is intended for use in network testing, measurement and
|
||||
management.
|
||||
Because of the load it can impose on the network, it is unwise to use
|
||||
.Nm
|
||||
during normal operations or from automated scripts.
|
||||
.\" .Sh ICMP PACKET DETAILS
|
||||
.\" An IP header without options is 20 bytes.
|
||||
.\" An
|
||||
.\" .Tn ICMP
|
||||
.\" .Tn ECHO_REQUEST
|
||||
.\" packet contains an additional 8 bytes worth of
|
||||
.\" .Tn ICMP
|
||||
.\" header followed by an arbitrary amount of data.
|
||||
.\" When a
|
||||
.\" .Ar packetsize
|
||||
.\" is given, this indicated the size of this extra piece of data
|
||||
.\" .Pq the default is 56 .
|
||||
.\" Thus the amount of data received inside of an IP packet of type
|
||||
.\" .Tn ICMP
|
||||
.\" .Tn ECHO_REPLY
|
||||
.\" will always be 8 bytes more than the requested data space
|
||||
.\" .Pq the Tn ICMP header .
|
||||
.\" .Pp
|
||||
.\" If the data space is at least eight bytes large,
|
||||
.\" .Nm
|
||||
.\" uses the first eight bytes of this space to include a timestamp which
|
||||
.\" it uses in the computation of round trip times.
|
||||
.\" If less than eight bytes of pad are specified, no round trip times are
|
||||
.\" given.
|
||||
.Sh DUPLICATE AND DAMAGED PACKETS
|
||||
.Nm Ping6
|
||||
will report duplicate and damaged packets.
|
||||
Duplicate packets should never occur when pinging a unicast address,
|
||||
and seem to be caused by
|
||||
inappropriate link-level retransmissions.
|
||||
Duplicates may occur in many situations and are rarely
|
||||
.Pq if ever
|
||||
a good sign, although the presence of low levels of duplicates may not
|
||||
always be cause for alarm.
|
||||
Duplicates are expected when pinging a broadcast or multicast address,
|
||||
since they are not really duplicates but replies from different hosts
|
||||
to the same request.
|
||||
.Pp
|
||||
Damaged packets are obviously serious cause for alarm and often
|
||||
indicate broken hardware somewhere in the
|
||||
.Nm ping
|
||||
packet's path
|
||||
.Pq in the network or in the hosts .
|
||||
.Sh TRYING DIFFERENT DATA PATTERNS
|
||||
The
|
||||
(inter)network
|
||||
layer should never treat packets differently depending on the data
|
||||
contained in the data portion.
|
||||
Unfortunately, data-dependent problems have been known to sneak into
|
||||
networks and remain undetected for long periods of time.
|
||||
In many cases the particular pattern that will have problems is something
|
||||
that does not have sufficient
|
||||
.Dq transitions ,
|
||||
such as all ones or all zeros, or a pattern right at the edge, such as
|
||||
almost all zeros.
|
||||
It is not
|
||||
necessarily enough to specify a data pattern of all zeros (for example)
|
||||
on the command line because the pattern that is of interest is
|
||||
at the data link level, and the relationship between what you type and
|
||||
what the controllers transmit can be complicated.
|
||||
.Pp
|
||||
This means that if you have a data-dependent problem you will probably
|
||||
have to do a lot of testing to find it.
|
||||
If you are lucky, you may manage to find a file that either
|
||||
cannot
|
||||
be sent across your network or that takes much longer to transfer than
|
||||
other similar length files.
|
||||
You can then examine this file for repeated patterns that you can test
|
||||
using the
|
||||
.Fl p
|
||||
option of
|
||||
.Nm Ns .
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Nm
|
||||
command returns an exit status of zero if at least one response was
|
||||
heard from the specified
|
||||
.Ar host ;
|
||||
a status of two if the transmission was successful but no responses
|
||||
were received; or another value
|
||||
.Pq from Aq Pa sysexits.h
|
||||
if an error occurred.
|
||||
.Sh SEE ALSO
|
||||
.Xr netstat 1 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr routed 8 ,
|
||||
.Xr ping 8 ,
|
||||
.Xr traceroute 8 ,
|
||||
.Xr traceroute6 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm ping
|
||||
command appeared in
|
||||
.Bx 4.3 .
|
||||
.Nm Ping6
|
||||
command with IPv6 support first appeared in WIDE Hydrangea IPv6 protocol stack
|
||||
kit.
|
||||
.\" .Sh BUGS
|
||||
.\" (to be written)
|
1549
sbin/ping6/ping6.c
Normal file
1549
sbin/ping6/ping6.c
Normal file
File diff suppressed because it is too large
Load Diff
29
sbin/rtsol/Makefile
Normal file
29
sbin/rtsol/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright (c) 1996 WIDE Project. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modifications, are permitted provided that the above copyright notice
|
||||
# and this paragraph are duplicated in all such forms and that any
|
||||
# documentation, advertising materials, and other materials related to
|
||||
# such distribution and use acknowledge that the software was developed
|
||||
# by the WIDE Project, Japan. The name of the Project may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
|
||||
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE.
|
||||
# $FreeBSD$
|
||||
|
||||
SRCDIR= ${.CURDIR}/../../usr.sbin/rtsold
|
||||
|
||||
PROG= rtsol
|
||||
SRCS= rtsold.c rtsol.c if.c probe.c dump.c
|
||||
|
||||
CFLAGS+=-DINET6
|
||||
LDADD+= -lkvm
|
||||
DPADD+= ${LIBKVM}
|
||||
|
||||
NOMAN= yes
|
||||
|
||||
.PATH: ${SRCDIR}
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -777,7 +777,7 @@ init_newprefix(struct in6_rrenumreq *irr, struct ifprefix *ifpr,
|
||||
return error;
|
||||
rap->ra_ifid = orap->ra_ifid;
|
||||
rap->ra_flags.anycast = (orap->ra_addr != NULL &&
|
||||
(orap->ra_addr->ia_flags &
|
||||
(orap->ra_addr->ia6_flags &
|
||||
IN6_IFF_ANYCAST) != 0) ? 1 : 0;
|
||||
LIST_INSERT_HEAD(&rpp->rp_addrhead, rap, ra_entry);
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ BINGRP= kmem
|
||||
BINMODE=2555
|
||||
DPADD= ${LIBKVM} ${LIBIPX} ${LIBNETGRAPH}
|
||||
LDADD= -lkvm -lipx -lnetgraph
|
||||
CFLAGS+= -DINET6
|
||||
CFLAGS+=-DINET6
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -390,23 +390,14 @@ ip6_stats(off, name)
|
||||
printf("\tMbuf statistics:\n");
|
||||
printf("\t\t%lu one mbuf\n", ip6stat.ip6s_m1);
|
||||
for (first = 1, i = 0; i < 32; i++) {
|
||||
char ifbuf[IFNAMSIZ];
|
||||
if (ip6stat.ip6s_m2m[i] != 0) {
|
||||
if (first) {
|
||||
printf("\t\ttwo or more mbuf:\n");
|
||||
first = 0;
|
||||
}
|
||||
printf("\t\t\t"
|
||||
#ifdef notyet
|
||||
"%s"
|
||||
#else
|
||||
"if%d"
|
||||
#endif
|
||||
"= %ld\n",
|
||||
#ifdef notyet
|
||||
printf("\t\t\t%s= %ld\n",
|
||||
if_indextoname(i, ifbuf),
|
||||
#else
|
||||
i,
|
||||
#endif
|
||||
ip6stat.ip6s_m2m[i]);
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +129,11 @@ static struct nlist nl[] = {
|
||||
{ "_ip6stat" },
|
||||
#define N_ICMP6STAT 29
|
||||
{ "_icmp6stat" },
|
||||
#ifdef notyet
|
||||
#define N_IPSECSTAT 30
|
||||
{ "_ipsecstat" },
|
||||
#define N_IPSEC6STAT 31
|
||||
{ "_ipsec6stat" },
|
||||
#ifdef notyet
|
||||
#define N_PIM6STAT 32
|
||||
{ "_pim6stat" },
|
||||
#define N_MRT6PROTO 33
|
||||
|
@ -605,7 +605,7 @@ p_rtentry(rt)
|
||||
WID_DST);
|
||||
p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST,
|
||||
#ifdef INET6
|
||||
kgetsa(rt->rt_gateway)->sa_family == AF_INET6 ? WID_GW6 :
|
||||
addr.u_sa.sa_family == AF_INET6 ? WID_GW6 :
|
||||
#endif
|
||||
WID_GW);
|
||||
p_flags(rt->rt_flags, "%-6.6s ");
|
||||
@ -763,16 +763,17 @@ netname6(sa6, mask)
|
||||
u_char *p = (u_char *)mask;
|
||||
u_char *lim;
|
||||
int masklen, illegal = 0;
|
||||
#ifdef notyet
|
||||
int flag = NI_WITHSCOPEID;
|
||||
#endif
|
||||
|
||||
if (mask) {
|
||||
for (masklen = 0, lim = p + 16; p < lim; p++) {
|
||||
if (*p == 0xff)
|
||||
masklen += 8;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (p < lim) {
|
||||
switch (*p) {
|
||||
case 0xff:
|
||||
masklen += 8;
|
||||
break;
|
||||
case 0xfe:
|
||||
masklen += 7;
|
||||
break;
|
||||
@ -810,14 +811,10 @@ netname6(sa6, mask)
|
||||
if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr))
|
||||
return("default");
|
||||
|
||||
#ifdef notyet
|
||||
if (nflag)
|
||||
flag |= NI_NUMERICHOST;
|
||||
getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, line, sizeof(line),
|
||||
NULL, 0, flag);
|
||||
#else
|
||||
inet_ntop(AF_INET6, (void *)&sa6->sin6_addr, line, sizeof(line));
|
||||
#endif
|
||||
|
||||
if (nflag)
|
||||
sprintf(&line[strlen(line)], "/%d", masklen);
|
||||
@ -829,37 +826,14 @@ char *
|
||||
routename6(sa6)
|
||||
struct sockaddr_in6 *sa6;
|
||||
{
|
||||
#ifdef notyet
|
||||
static char line[MAXHOSTNAMELEN + 1];
|
||||
int flag = NI_WITHSCOPEID;
|
||||
|
||||
if (nflag)
|
||||
flag |= NI_NUMERICHOST;
|
||||
#else
|
||||
register char *cp;
|
||||
#endif
|
||||
static char line[MAXHOSTNAMELEN + 1];
|
||||
struct hostent *hp;
|
||||
|
||||
#ifdef notyet
|
||||
getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, line, sizeof(line),
|
||||
NULL, 0, flag);
|
||||
#else
|
||||
cp = 0;
|
||||
if (!nflag) {
|
||||
hp = gethostbyaddr((char *)&sa6->sin6_addr,
|
||||
sizeof(sa6->sin6_addr), AF_INET6);
|
||||
if (hp) {
|
||||
cp = hp->h_name;
|
||||
trimdomain(cp);
|
||||
}
|
||||
}
|
||||
if (cp) {
|
||||
strncpy(line, cp, sizeof(line) - 1);
|
||||
line[sizeof(line) - 1] = '\0';
|
||||
} else
|
||||
inet_ntop(AF_INET6, (void *)&sa6->sin6_addr, line,
|
||||
sizeof(line));
|
||||
#endif
|
||||
|
||||
return line;
|
||||
}
|
||||
|
21
usr.sbin/gifconfig/Makefile
Normal file
21
usr.sbin/gifconfig/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (c) 1996 WIDE Project. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modifications, are permitted provided that the above copyright notice
|
||||
# and this paragraph are duplicated in all such forms and that any
|
||||
# documentation, advertising materials, and other materials related to
|
||||
# such distribution and use acknowledge that the software was developed
|
||||
# by the WIDE Project, Japan. The name of the Project may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
|
||||
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE.
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= gifconfig
|
||||
MAN8= gifconfig.8
|
||||
|
||||
CFLAGS+=-DINET6
|
||||
|
||||
.include <bsd.prog.mk>
|
140
usr.sbin/gifconfig/gifconfig.8
Normal file
140
usr.sbin/gifconfig/gifconfig.8
Normal file
@ -0,0 +1,140 @@
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" 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 project 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 PROJECT 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 PROJECT 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.
|
||||
.\"
|
||||
.\" $Id: gifconfig.8,v 1.2 1999/10/07 04:25:54 itojun Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 17, 1998
|
||||
.Dt GIFCONFIG 8
|
||||
.Os KAME
|
||||
.\"
|
||||
.Sh NAME
|
||||
.Nm gifconfig
|
||||
.Nd configure generic IP tunnel
|
||||
.\"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Ar interface
|
||||
.Op Ar af
|
||||
.Op Ar physsrc physdest
|
||||
.Nm gifconfig
|
||||
.Fl a
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
configures the physical address for the generic IP tunnel
|
||||
inteface, such as "gif0".
|
||||
Argument
|
||||
.Ar physsrc
|
||||
and
|
||||
.Ar physdest
|
||||
are interpreted as the outer source/destination address for
|
||||
encapsulating IPv4/v6 header.
|
||||
Argument
|
||||
.Ar af
|
||||
specifies the address family for
|
||||
.Ar physsrc
|
||||
and
|
||||
.Ar physdest .
|
||||
.Ar Af
|
||||
can be
|
||||
.Li inet
|
||||
or
|
||||
.Li inet6 ,
|
||||
and will be treated as
|
||||
.Li inet
|
||||
if ommitted.
|
||||
.Pp
|
||||
.Nm
|
||||
takes the following optional argument:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a
|
||||
Display information associated all generic IP tunnel interfaces.
|
||||
.El
|
||||
.Pp
|
||||
Please note that it is very easy to create infinite routing loop,
|
||||
when you configure tunnel over same address family
|
||||
.Po
|
||||
e.g. IPv4-over-IPv4
|
||||
.Pc .
|
||||
.\"
|
||||
.Sh EXAMPLES
|
||||
If you would like to configure IPv6 over IPv4
|
||||
.Pq aka IPv6 in IPv4
|
||||
tunnel between
|
||||
.Li 10.1.1.1
|
||||
and
|
||||
.Li 10.2.3.4 ,
|
||||
you should perform the following command:
|
||||
.Bd -literal -offset
|
||||
# gifconfig gif0 inet 10.1.1.1 10.2.3.4
|
||||
.Ed
|
||||
.Pp
|
||||
.\" To use the
|
||||
.\" .Li 0.0.0.0
|
||||
.\" feature to establish a tunnel from host1 to host3
|
||||
.\" which will encapsulate and carry packets from host2, on host1 do:
|
||||
.\" .Bd -literal -offset
|
||||
.\" # ifconfig gif0 inet host1 127.0.0.2 # assign an address to gif0
|
||||
.\" # gifconfig gif0 inet host1 0.0.0.0 # assign encapsulation addresses
|
||||
.\" # route add host2 host3 -ifp gif0: # encap host2 packets, send to host3
|
||||
.\" .Ed
|
||||
.\" .Pp
|
||||
.\" Note: the
|
||||
.\" .Fl ifp
|
||||
.\" option to route does not work as documented in
|
||||
.\" most versions of FreeBSD.
|
||||
.\" .Pp
|
||||
.\" On host3 do:
|
||||
.\" .Bd -literal -offset
|
||||
.\" # ifconfig gif0 inet host3 127.0.0.2 # assign an address to gif0
|
||||
.\" # gifconfig gif0 inet host3 0.0.0.0 # assign encapsulation addresses
|
||||
.\" .Ed
|
||||
.\" .Pp
|
||||
.\" Now if you ping host2 from host1, the packets should be encapsulated
|
||||
.\" with outer source address = host1 and outer destination address = host3,
|
||||
.\" and delivered to host3.
|
||||
.\" host3 will decapsulate the packet and deliver it normally to host2.
|
||||
.\" .Pp
|
||||
This is also possible to use IPv6 as outer proto, by replacing
|
||||
.Li inet
|
||||
to
|
||||
.Li inet6 ,
|
||||
and IPv4 addresses to some appropriate IPv6 addresses in above example.
|
||||
.\"
|
||||
.Sh RETURN VALUES
|
||||
The command exits with exit status of 1 on errors, 0 on success.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr gif 4 ,
|
||||
.Xr ifconfig 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command first appeared in WIDE Hydrangea IPv6 protocol stack kit.
|
||||
.\" .Sh BUGS
|
||||
.\" (to be written)
|
834
usr.sbin/gifconfig/gifconfig.c
Normal file
834
usr.sbin/gifconfig/gifconfig.c
Normal file
@ -0,0 +1,834 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* gifconfig, derived from ifconfig
|
||||
*
|
||||
* @(#) Copyright (c) 1983, 1993\n\
|
||||
* The Regents of the University of California. All rights reserved.\n
|
||||
*
|
||||
* @(#)ifconfig.c 8.2 (Berkeley) 2/16/94
|
||||
*/
|
||||
|
||||
/*
|
||||
* 951109 - Andrew@pubnix.net - Changed to iterative buffer growing mechanism
|
||||
* for ifconfig -a so all interfaces are queried.
|
||||
*
|
||||
* 960101 - peter@freebsd.org - Blow away the SIOCGIFCONF code and use
|
||||
* sysctl() to get the structured interface conf
|
||||
* and parse the messages in there. REALLY UGLY!
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
#include <net/if_var.h>
|
||||
#endif /* __FreeBSD__ >= 3 */
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <sys/protosw.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <nlist.h>
|
||||
#include <kvm.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
struct ifreq ifr;
|
||||
struct ifaliasreq addreq;
|
||||
#ifdef INET6
|
||||
struct in6_ifreq in6_ifr;
|
||||
struct in6_aliasreq in6_addreq;
|
||||
#endif
|
||||
|
||||
char name[32];
|
||||
int flags;
|
||||
int metric;
|
||||
int mtu;
|
||||
int setpsrc = 0;
|
||||
int s;
|
||||
kvm_t *kvmd;
|
||||
extern int errno;
|
||||
|
||||
#ifdef INET6
|
||||
char ntop_buf[INET6_ADDRSTRLEN]; /*inet_ntop()*/
|
||||
#endif
|
||||
|
||||
void setifpsrc __P((char *, int));
|
||||
void setifpdst __P((char *, int));
|
||||
void setifflags __P((char *, int));
|
||||
|
||||
|
||||
#define NEXTARG 0xffffff
|
||||
|
||||
struct cmd {
|
||||
char *c_name;
|
||||
int c_parameter; /* NEXTARG means next argv */
|
||||
void (*c_func) __P((char *, int));
|
||||
} cmds[] = {
|
||||
{ "up", IFF_UP, setifflags } ,
|
||||
{ "down", -IFF_UP, setifflags },
|
||||
{ 0, 0, setifpsrc },
|
||||
{ 0, 0, setifpdst },
|
||||
};
|
||||
|
||||
/*
|
||||
* XNS support liberally adapted from code written at the University of
|
||||
* Maryland principally by James O'Toole and Chris Torek.
|
||||
*/
|
||||
int main __P((int, char *[]));
|
||||
void status __P((void));
|
||||
void phys_status __P((int));
|
||||
void in_status __P((int));
|
||||
#ifdef INET6
|
||||
void in6_status __P((int));
|
||||
#endif
|
||||
void ether_status __P((int));
|
||||
void Perror __P((char *));
|
||||
void in_getaddr __P((char *, int));
|
||||
#ifdef INET6
|
||||
void in6_getaddr __P((char *, int));
|
||||
void in6_getprefix __P((char *, int));
|
||||
#endif
|
||||
void printb __P((char *, unsigned int, char *));
|
||||
int prefix __P((void *, int));
|
||||
|
||||
char ntop_buf[INET6_ADDRSTRLEN];
|
||||
|
||||
/* Known address families */
|
||||
struct afswtch {
|
||||
char *af_name;
|
||||
short af_af;
|
||||
void (*af_status) __P((int));
|
||||
void (*af_getaddr) __P((char *, int));
|
||||
void (*af_getprefix) __P((char *, int));
|
||||
u_long af_pifaddr;
|
||||
caddr_t af_addreq;
|
||||
caddr_t af_req;
|
||||
} afs[] = {
|
||||
#define C(x) ((caddr_t) &x)
|
||||
{ "inet", AF_INET, in_status, in_getaddr, 0,
|
||||
SIOCSIFPHYADDR, C(addreq), C(ifr) },
|
||||
#ifdef INET6
|
||||
{ "inet6", AF_INET6, in6_status, in6_getaddr, in6_getprefix,
|
||||
SIOCSIFPHYADDR_IN6, C(in6_addreq), C(in6_ifr) },
|
||||
#endif
|
||||
{ "ether", AF_INET, ether_status, NULL, NULL }, /* XXX not real!! */
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
struct afswtch *afp = NULL; /*the address family being set or asked about*/
|
||||
|
||||
void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
|
||||
int ifconfig __P((int argc, char *argv[], int af, struct afswtch *rafp));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Expand the compacted form of addresses as returned via the
|
||||
* configuration read via sysctl().
|
||||
*/
|
||||
|
||||
#define ROUNDUP(a) \
|
||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
|
||||
|
||||
void
|
||||
rt_xaddrs(cp, cplim, rtinfo)
|
||||
caddr_t cp, cplim;
|
||||
struct rt_addrinfo *rtinfo;
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int i;
|
||||
|
||||
memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
|
||||
for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
|
||||
if ((rtinfo->rti_addrs & (1 << i)) == 0)
|
||||
continue;
|
||||
rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
|
||||
ADVANCE(cp, sa);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Grunge for new-style sysctl() decoding.. :-(
|
||||
* Apologies to the world for committing gross things like this in 1996..
|
||||
*/
|
||||
struct if_msghdr *ifm;
|
||||
struct ifa_msghdr *ifam;
|
||||
struct sockaddr_dl *sdl;
|
||||
struct rt_addrinfo info;
|
||||
char *buf, *lim, *next;
|
||||
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int af = AF_INET;
|
||||
struct afswtch *rafp = NULL;
|
||||
size_t needed;
|
||||
int mib[6];
|
||||
int all;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: gifconfig interface %s",
|
||||
"[ af ] physsrc physdst\n");
|
||||
exit(1);
|
||||
}
|
||||
argc--, argv++;
|
||||
strncpy(name, *argv, sizeof(name));
|
||||
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||
argc--, argv++;
|
||||
if (argc > 0) {
|
||||
for (afp = rafp = afs; rafp->af_name; rafp++)
|
||||
if (strcmp(rafp->af_name, *argv) == 0) {
|
||||
afp = rafp; argc--; argv++;
|
||||
break;
|
||||
}
|
||||
rafp = afp;
|
||||
af = ifr.ifr_addr.sa_family = rafp->af_af;
|
||||
}
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[2] = 0;
|
||||
mib[3] = 0; /* address family */
|
||||
mib[4] = NET_RT_IFLIST;
|
||||
mib[5] = 0;
|
||||
|
||||
/* if particular family specified, only ask about it */
|
||||
if (afp) {
|
||||
mib[3] = afp->af_af;
|
||||
}
|
||||
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
|
||||
errx(1, "iflist-sysctl-estimate");
|
||||
if ((buf = malloc(needed)) == NULL)
|
||||
errx(1, "malloc");
|
||||
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
|
||||
errx(1, "actual retrieval of interface table");
|
||||
lim = buf + needed;
|
||||
|
||||
all = 0;
|
||||
if (strcmp(name, "-a") == 0)
|
||||
all = 1; /* All interfaces */
|
||||
else if (strcmp(name, "-au") == 0)
|
||||
all = 2; /* All IFF_UPinterfaces */
|
||||
else if (strcmp(name, "-ad") == 0)
|
||||
all = 3; /* All !IFF_UP interfaces */
|
||||
|
||||
for (next = buf; next < lim; next += ifm->ifm_msglen) {
|
||||
|
||||
ifm = (struct if_msghdr *)next;
|
||||
|
||||
/* XXX: Swallow up leftover NEWADDR messages */
|
||||
if (ifm->ifm_type == RTM_NEWADDR)
|
||||
continue;
|
||||
|
||||
if (ifm->ifm_type == RTM_IFINFO) {
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
flags = ifm->ifm_flags;
|
||||
} else {
|
||||
errx(1, "out of sync parsing NET_RT_IFLIST");
|
||||
}
|
||||
|
||||
switch(all) {
|
||||
case -1:
|
||||
case 0:
|
||||
if (strlen(name) != sdl->sdl_nlen)
|
||||
continue; /* not same len */
|
||||
if (strncmp(name, sdl->sdl_data, sdl->sdl_nlen) != 0)
|
||||
continue; /* not same name */
|
||||
break;
|
||||
case 1:
|
||||
break; /* always do it */
|
||||
case 2:
|
||||
if ((flags & IFF_UP) == 0)
|
||||
continue; /* not up */
|
||||
break;
|
||||
case 3:
|
||||
if (flags & IFF_UP)
|
||||
continue; /* not down */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's just do it for gif only
|
||||
*/
|
||||
if (sdl->sdl_type != IFT_GIF) {
|
||||
if (all != 0)
|
||||
continue;
|
||||
|
||||
fprintf(stderr, "gifconfig: %s is not gif.\n",
|
||||
ifr.ifr_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (all > 0) {
|
||||
strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
|
||||
name[sdl->sdl_nlen] = '\0';
|
||||
}
|
||||
|
||||
if ((s = socket(af, SOCK_DGRAM, 0)) < 0) {
|
||||
perror("gifconfig: socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ifconfig(argc,argv,af,rafp);
|
||||
|
||||
close(s);
|
||||
|
||||
if (all == 0) {
|
||||
all = -1; /* flag it as 'done' */
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
|
||||
if (all == 0)
|
||||
errx(1, "interface %s does not exist", name);
|
||||
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ifconfig(argc, argv, af, rafp)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int af;
|
||||
struct afswtch *rafp;
|
||||
{
|
||||
|
||||
af = 0; /*fool gcc*/
|
||||
|
||||
strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
|
||||
#ifdef INET6
|
||||
strncpy(in6_ifr.ifr_name, name, sizeof in6_ifr.ifr_name);
|
||||
#endif /* INET6 */
|
||||
|
||||
if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)
|
||||
perror("ioctl (SIOCGIFMETRIC)");
|
||||
else
|
||||
metric = ifr.ifr_metric;
|
||||
|
||||
#if defined(SIOCGIFMTU) && !defined(__OpenBSD__)
|
||||
if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0)
|
||||
perror("ioctl (SIOCGIFMTU)");
|
||||
else
|
||||
mtu = ifr.ifr_mtu;
|
||||
#else
|
||||
mtu = 0;
|
||||
#endif
|
||||
|
||||
if (argc == 0) {
|
||||
status();
|
||||
return(0);
|
||||
}
|
||||
|
||||
while (argc > 0) {
|
||||
register struct cmd *p;
|
||||
|
||||
for (p = cmds; p->c_name; p++)
|
||||
if (strcmp(*argv, p->c_name) == 0)
|
||||
break;
|
||||
if (p->c_name == 0 && setpsrc)
|
||||
p++; /* got src, do dst */
|
||||
if (p->c_func) {
|
||||
if (p->c_parameter == NEXTARG) {
|
||||
if (argv[1] == NULL)
|
||||
errx(1, "'%s' requires argument",
|
||||
p->c_name);
|
||||
(*p->c_func)(argv[1], 0);
|
||||
argc--, argv++;
|
||||
} else
|
||||
(*p->c_func)(*argv, p->c_parameter);
|
||||
}
|
||||
argc--, argv++;
|
||||
}
|
||||
if (1 /*newaddr*/) {
|
||||
strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name);
|
||||
if (ioctl(s, rafp->af_pifaddr, rafp->af_addreq) < 0)
|
||||
Perror("ioctl (SIOCSIFPHYADDR)");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#define PSRC 0
|
||||
#define PDST 1
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
setifpsrc(addr, param)
|
||||
char *addr;
|
||||
int param;
|
||||
{
|
||||
param = 0; /*fool gcc*/
|
||||
(*afp->af_getaddr)(addr, PSRC);
|
||||
setpsrc = 1;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
setifpdst(addr, param)
|
||||
char *addr;
|
||||
int param;
|
||||
{
|
||||
param = 0; /*fool gcc*/
|
||||
(*afp->af_getaddr)(addr, PDST);
|
||||
}
|
||||
|
||||
void
|
||||
setifflags(vname, value)
|
||||
char *vname;
|
||||
int value;
|
||||
{
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
|
||||
Perror("ioctl (SIOCGIFFLAGS)");
|
||||
exit(1);
|
||||
}
|
||||
strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
|
||||
flags = ifr.ifr_flags;
|
||||
|
||||
if (value < 0) {
|
||||
value = -value;
|
||||
flags &= ~value;
|
||||
} else
|
||||
flags |= value;
|
||||
ifr.ifr_flags = flags;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
|
||||
Perror(vname);
|
||||
}
|
||||
|
||||
#define IFFBITS \
|
||||
"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
|
||||
\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
|
||||
|
||||
/*
|
||||
* Print the status of the interface. If an address family was
|
||||
* specified, show it and it only; otherwise, show them all.
|
||||
*/
|
||||
void
|
||||
status()
|
||||
{
|
||||
struct afswtch *p = NULL;
|
||||
char *mynext;
|
||||
struct if_msghdr *myifm;
|
||||
|
||||
printf("%s: ", name);
|
||||
printb("flags", flags, IFFBITS);
|
||||
if (metric)
|
||||
printf(" metric %d", metric);
|
||||
if (mtu)
|
||||
printf(" mtu %d", mtu);
|
||||
putchar('\n');
|
||||
|
||||
/*
|
||||
* XXX: Sigh. This is bad, I know. At this point, we may have
|
||||
* *zero* RTM_NEWADDR's, so we have to "feel the water" before
|
||||
* incrementing the loop. One day, I might feel inspired enough
|
||||
* to get the top level loop to pass a count down here so we
|
||||
* dont have to mess with this. -Peter
|
||||
*/
|
||||
myifm = ifm;
|
||||
|
||||
while (1) {
|
||||
|
||||
mynext = next + ifm->ifm_msglen;
|
||||
|
||||
if (mynext >= lim)
|
||||
break;
|
||||
|
||||
myifm = (struct if_msghdr *)mynext;
|
||||
|
||||
if (myifm->ifm_type != RTM_NEWADDR)
|
||||
break;
|
||||
|
||||
next = mynext;
|
||||
|
||||
ifm = (struct if_msghdr *)next;
|
||||
|
||||
ifam = (struct ifa_msghdr *)myifm;
|
||||
info.rti_addrs = ifam->ifam_addrs;
|
||||
|
||||
/* Expand the compacted addresses */
|
||||
rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
|
||||
&info);
|
||||
|
||||
if (afp) {
|
||||
if (afp->af_af == info.rti_info[RTAX_IFA]->sa_family &&
|
||||
afp->af_status != ether_status) {
|
||||
p = afp;
|
||||
if (p->af_status != ether_status)
|
||||
(*p->af_status)(1);
|
||||
}
|
||||
} else for (p = afs; p->af_name; p++) {
|
||||
if (p->af_af == info.rti_info[RTAX_IFA]->sa_family &&
|
||||
p->af_status != ether_status)
|
||||
(*p->af_status)(0);
|
||||
}
|
||||
}
|
||||
if (afp == NULL || afp->af_status == ether_status)
|
||||
ether_status(0);
|
||||
else if (afp && !p) {
|
||||
warnx("%s has no %s IFA address!", name, afp->af_name);
|
||||
}
|
||||
|
||||
phys_status(0);
|
||||
}
|
||||
|
||||
void
|
||||
phys_status(force)
|
||||
int force;
|
||||
{
|
||||
char psrcaddr[256];
|
||||
char pdstaddr[256];
|
||||
char hostname[NI_MAXHOST];
|
||||
u_long srccmd, dstcmd;
|
||||
int flags = NI_NUMERICHOST;
|
||||
struct ifreq *ifrp;
|
||||
char *ver = "";
|
||||
|
||||
force = 0; /*fool gcc*/
|
||||
|
||||
psrcaddr[0] = pdstaddr[0] = '\0';
|
||||
|
||||
#ifdef INET6
|
||||
srccmd = SIOCGIFPSRCADDR_IN6;
|
||||
dstcmd = SIOCGIFPDSTADDR_IN6;
|
||||
ifrp = (struct ifreq *)&in6_ifr;
|
||||
#else /* INET6 */
|
||||
ifrp = ifr;
|
||||
srccmd = SIOCGIFPSRCADDR;
|
||||
dstcmd = SIOCGIFPDSTADDR;
|
||||
#endif /* INET6 */
|
||||
|
||||
if (0 <= ioctl(s, srccmd, (caddr_t)ifrp)) {
|
||||
getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len,
|
||||
hostname, NI_MAXHOST, 0, 0, flags);
|
||||
#ifdef INET6
|
||||
if (ifrp->ifr_addr.sa_family == AF_INET6)
|
||||
ver = "6";
|
||||
#endif /* INET6 */
|
||||
sprintf(psrcaddr, "inet%s %s", ver, hostname);
|
||||
}
|
||||
if (0 <= ioctl(s, dstcmd, (caddr_t)ifrp)) {
|
||||
getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len,
|
||||
hostname, NI_MAXHOST, 0, 0, flags);
|
||||
sprintf(pdstaddr, "%s", hostname);
|
||||
}
|
||||
printf("\tphysical address %s --> %s\n", psrcaddr, pdstaddr);
|
||||
}
|
||||
|
||||
void
|
||||
in_status(force)
|
||||
int force;
|
||||
{
|
||||
struct sockaddr_in *sin, null_sin;
|
||||
#if 0
|
||||
char *inet_ntoa();
|
||||
#endif
|
||||
|
||||
memset(&null_sin, 0, sizeof(null_sin));
|
||||
|
||||
sin = (struct sockaddr_in *)info.rti_info[RTAX_IFA];
|
||||
if (!sin || sin->sin_family != AF_INET) {
|
||||
if (!force)
|
||||
return;
|
||||
/* warnx("%s has no AF_INET IFA address!", name); */
|
||||
sin = &null_sin;
|
||||
}
|
||||
printf("\tinet %s ", inet_ntoa(sin->sin_addr));
|
||||
|
||||
if (flags & IFF_POINTOPOINT) {
|
||||
/* note RTAX_BRD overlap with IFF_BROADCAST */
|
||||
sin = (struct sockaddr_in *)info.rti_info[RTAX_BRD];
|
||||
if (!sin)
|
||||
sin = &null_sin;
|
||||
printf("--> %s ", inet_ntoa(sin->sin_addr));
|
||||
}
|
||||
|
||||
sin = (struct sockaddr_in *)info.rti_info[RTAX_NETMASK];
|
||||
if (!sin)
|
||||
sin = &null_sin;
|
||||
printf("netmask 0x%x ", (u_int32_t)ntohl(sin->sin_addr.s_addr));
|
||||
|
||||
if (flags & IFF_BROADCAST) {
|
||||
/* note RTAX_BRD overlap with IFF_POINTOPOINT */
|
||||
sin = (struct sockaddr_in *)info.rti_info[RTAX_BRD];
|
||||
if (sin && sin->sin_addr.s_addr != 0)
|
||||
printf("broadcast %s", inet_ntoa(sin->sin_addr));
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
void
|
||||
in6_status(force)
|
||||
int force;
|
||||
{
|
||||
struct sockaddr_in6 *sin, null_sin;
|
||||
#if 0
|
||||
char *inet_ntop();
|
||||
#endif
|
||||
|
||||
|
||||
memset(&null_sin, 0, sizeof(null_sin));
|
||||
|
||||
sin = (struct sockaddr_in6 *)info.rti_info[RTAX_IFA];
|
||||
if (!sin || sin->sin6_family != AF_INET6) {
|
||||
if (!force)
|
||||
return;
|
||||
/* warnx("%s has no AF_INET6 IFA address!", name); */
|
||||
sin = &null_sin;
|
||||
}
|
||||
printf("\tinet6 %s ", inet_ntop(AF_INET6, &sin->sin6_addr,
|
||||
ntop_buf, sizeof(ntop_buf)));
|
||||
|
||||
if (flags & IFF_POINTOPOINT) {
|
||||
/* note RTAX_BRD overlap with IFF_BROADCAST */
|
||||
sin = (struct sockaddr_in6 *)info.rti_info[RTAX_BRD];
|
||||
/*
|
||||
* some of ther interfaces do not have valid destination
|
||||
* address.
|
||||
*/
|
||||
if (sin->sin6_family == AF_INET6) {
|
||||
if (!sin)
|
||||
sin = &null_sin;
|
||||
printf("--> %s ", inet_ntop(AF_INET6, &sin->sin6_addr,
|
||||
ntop_buf, sizeof(ntop_buf)));
|
||||
}
|
||||
}
|
||||
|
||||
sin = (struct sockaddr_in6 *)info.rti_info[RTAX_NETMASK];
|
||||
if (!sin)
|
||||
sin = &null_sin;
|
||||
printf(" prefixlen %d ", prefix(&sin->sin6_addr,
|
||||
sizeof(struct in6_addr)));
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
#endif /*INET6*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ether_status(dummy)
|
||||
int dummy;
|
||||
{
|
||||
char *cp;
|
||||
int n;
|
||||
|
||||
dummy = 0; /*fool gcc*/
|
||||
|
||||
cp = (char *)LLADDR(sdl);
|
||||
if ((n = sdl->sdl_alen) > 0) {
|
||||
if (sdl->sdl_type == IFT_ETHER)
|
||||
printf ("\tether ");
|
||||
else
|
||||
printf ("\tlladdr ");
|
||||
while (--n >= 0)
|
||||
printf("%02x%c",*cp++ & 0xff, n>0? ':' : ' ');
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Perror(cmd)
|
||||
char *cmd;
|
||||
{
|
||||
extern int errno;
|
||||
|
||||
switch (errno) {
|
||||
|
||||
case ENXIO:
|
||||
errx(1, "%s: no such interface", cmd);
|
||||
break;
|
||||
|
||||
case EPERM:
|
||||
errx(1, "%s: permission denied", cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
err(1, "%s", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
#define SIN(x) ((struct sockaddr_in *) &(x))
|
||||
struct sockaddr_in *sintab[] = {
|
||||
SIN(addreq.ifra_addr), SIN(addreq.ifra_dstaddr)};
|
||||
|
||||
void
|
||||
in_getaddr(s, which)
|
||||
char *s;
|
||||
int which;
|
||||
{
|
||||
register struct sockaddr_in *sin = sintab[which];
|
||||
struct hostent *hp;
|
||||
struct netent *np;
|
||||
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
|
||||
if (inet_aton(s, &sin->sin_addr))
|
||||
;
|
||||
else if ((hp = gethostbyname(s)) != NULL)
|
||||
bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
|
||||
else if ((np = getnetbyname(s)) != NULL)
|
||||
sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
|
||||
else
|
||||
errx(1, "%s: bad value", s);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
#define SIN6(x) ((struct sockaddr_in6 *) &(x))
|
||||
struct sockaddr_in6 *sin6tab[] = {
|
||||
SIN6(in6_addreq.ifra_addr), SIN6(in6_addreq.ifra_dstaddr)};
|
||||
|
||||
void
|
||||
in6_getaddr(s, which)
|
||||
char *s;
|
||||
int which;
|
||||
{
|
||||
register struct sockaddr_in6 *sin = sin6tab[which];
|
||||
|
||||
sin->sin6_len = sizeof(*sin);
|
||||
sin->sin6_family = AF_INET6;
|
||||
|
||||
if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1)
|
||||
errx(1, "%s: bad value", s);
|
||||
}
|
||||
|
||||
void
|
||||
in6_getprefix(plen, which)
|
||||
char *plen;
|
||||
int which;
|
||||
{
|
||||
register struct sockaddr_in6 *sin = sin6tab[which];
|
||||
register u_char *cp;
|
||||
int len = atoi(plen);
|
||||
|
||||
if ((len < 0) || (len > 128))
|
||||
errx(1, "%s: bad value", plen);
|
||||
sin->sin6_len = sizeof(*sin);
|
||||
sin->sin6_family = AF_INET6;
|
||||
if ((len == 0) || (len == 128)) {
|
||||
memset(&sin->sin6_addr, -1, sizeof(struct in6_addr));
|
||||
return;
|
||||
}
|
||||
for (cp = (u_char *)&sin->sin6_addr; len > 7; len -= 8)
|
||||
*cp++ = -1;
|
||||
*cp = (-1) << (8 - len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Print a value a la the %b format of the kernel's printf
|
||||
*/
|
||||
void
|
||||
printb(s, v, bits)
|
||||
char *s;
|
||||
register unsigned int v;
|
||||
register char *bits;
|
||||
{
|
||||
register int i, any = 0;
|
||||
register char c;
|
||||
|
||||
if (bits && *bits == 8)
|
||||
printf("%s=%o", s, v & 0xffff);
|
||||
else
|
||||
printf("%s=%x", s, v & 0xffff);
|
||||
bits++;
|
||||
if (bits) {
|
||||
putchar('<');
|
||||
while ((i = *bits++) != 0) {
|
||||
if ((v & (1 << (i-1))) != 0) {
|
||||
if (any)
|
||||
putchar(',');
|
||||
any = 1;
|
||||
for (; (c = *bits) > 32; bits++)
|
||||
putchar(c);
|
||||
} else
|
||||
for (; *bits > 32; bits++)
|
||||
;
|
||||
}
|
||||
putchar('>');
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
int
|
||||
prefix(val, size)
|
||||
void *val;
|
||||
int size;
|
||||
{
|
||||
register u_char *name = (u_char *)val;
|
||||
register int byte, bit, plen = 0;
|
||||
|
||||
for (byte = 0; byte < size; byte++, plen += 8)
|
||||
if (name[byte] != 0xff)
|
||||
break;
|
||||
if (byte == size)
|
||||
return (plen);
|
||||
for (bit = 7; bit != 0; bit--, plen++)
|
||||
if (!(name[byte] & (1 << bit)))
|
||||
break;
|
||||
for (; bit != 0; bit--)
|
||||
if (name[byte] & (1 << bit))
|
||||
return(0);
|
||||
byte++;
|
||||
for (; byte < size; byte++)
|
||||
if (name[byte])
|
||||
return(0);
|
||||
return (plen);
|
||||
}
|
||||
#endif /*INET6*/
|
14
usr.sbin/ifmcstat/Makefile
Normal file
14
usr.sbin/ifmcstat/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ifmcstat
|
||||
MAN8= ifmcstat.8
|
||||
|
||||
BINGRP= kmem
|
||||
BINMODE=2555
|
||||
LDADD= -lkvm
|
||||
DPADD= ${LIBKVM}
|
||||
|
||||
CFLAGS+=-DINET6
|
||||
|
||||
.include <bsd.prog.mk>
|
34
usr.sbin/ifmcstat/ifmcstat.8
Normal file
34
usr.sbin/ifmcstat/ifmcstat.8
Normal file
@ -0,0 +1,34 @@
|
||||
.\" Copyright (c) 1996 WIDE Project. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modifications, are permitted provided that the above copyright notice
|
||||
.\" and this paragraph are duplicated in all such forms and that any
|
||||
.\" documentation, advertising materials, and other materials related to
|
||||
.\" such distribution and use acknowledge that the software was developed
|
||||
.\" by the WIDE Project, Japan. The name of the Project may not be used to
|
||||
.\" endorse or promote products derived from this software without
|
||||
.\" specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
|
||||
.\" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
.\" LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
.\" A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 21, 1998
|
||||
.Dt IFMCSTAT 8
|
||||
.Os KAME
|
||||
.Sh NAME
|
||||
.Nm ifmcstat
|
||||
.Nd dump multicast group management statistics per interface
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm Ifmcstat
|
||||
dumps multicast group information in the kernel.
|
||||
.Pp
|
||||
There are no command-line options.
|
||||
.\"
|
||||
.\" .Sh SEE ALSO
|
||||
.\" RFC2080 -- IPng for IPv6. G. Malkin, R. Minnear. January 1997.
|
338
usr.sbin/ifmcstat/ifmcstat.c
Normal file
338
usr.sbin/ifmcstat/ifmcstat.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <kvm.h>
|
||||
#include <nlist.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
# include <net/if_var.h>
|
||||
#endif
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in.h>
|
||||
#ifndef __NetBSD__
|
||||
# ifdef __FreeBSD__
|
||||
# define KERNEL
|
||||
# endif
|
||||
# include <netinet/if_ether.h>
|
||||
# ifdef __FreeBSD__
|
||||
# undef KERNEL
|
||||
# endif
|
||||
#else
|
||||
# include <net/if_ether.h>
|
||||
#endif
|
||||
#include <netinet/in_var.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
kvm_t *kvmd;
|
||||
|
||||
struct nlist nl[] = {
|
||||
#define N_IFNET 0
|
||||
{ "_ifnet" },
|
||||
{ "" },
|
||||
};
|
||||
|
||||
const char *inet6_n2a __P((struct in6_addr *));
|
||||
int main __P((void));
|
||||
char *ifname __P((struct ifnet *));
|
||||
void kread __P((u_long, void *, int));
|
||||
#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
|
||||
void acmc __P((struct ether_multi *));
|
||||
#endif
|
||||
void if6_addrlist __P((struct ifaddr *));
|
||||
void in6_multilist __P((struct in6_multi *));
|
||||
struct in6_multi * in6_multientry __P((struct in6_multi *));
|
||||
|
||||
#if !defined(__NetBSD__) && !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(__OpenBSD__)
|
||||
#ifdef __bsdi__
|
||||
struct ether_addr {
|
||||
u_int8_t ether_addr_octet[6];
|
||||
};
|
||||
#endif
|
||||
static char *ether_ntoa __P((struct ether_addr *));
|
||||
#endif
|
||||
|
||||
#define KREAD(addr, buf, type) \
|
||||
kread((u_long)addr, (void *)buf, sizeof(type))
|
||||
|
||||
const char *inet6_n2a(p)
|
||||
struct in6_addr *p;
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(p))
|
||||
return "*";
|
||||
return inet_ntop(AF_INET6, (void *)p, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char buf[_POSIX2_LINE_MAX], ifname[IFNAMSIZ];
|
||||
struct ifnet *ifp, *nifp, ifnet;
|
||||
#ifndef __NetBSD__
|
||||
struct arpcom arpcom;
|
||||
#else
|
||||
struct ethercom ec;
|
||||
struct sockaddr_dl sdl;
|
||||
#endif
|
||||
|
||||
if ((kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf)) == NULL) {
|
||||
perror("kvm_openfiles");
|
||||
exit(1);
|
||||
}
|
||||
if (kvm_nlist(kvmd, nl) < 0) {
|
||||
perror("kvm_nlist");
|
||||
exit(1);
|
||||
}
|
||||
if (nl[N_IFNET].n_value == 0) {
|
||||
printf("symbol %s not found\n", nl[N_IFNET].n_name);
|
||||
exit(1);
|
||||
}
|
||||
KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *);
|
||||
while (ifp) {
|
||||
KREAD(ifp, &ifnet, struct ifnet);
|
||||
printf("%s:\n", if_indextoname(ifnet.if_index, ifname));
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
if6_addrlist(ifnet.if_addrlist.tqh_first);
|
||||
nifp = ifnet.if_list.tqe_next;
|
||||
#elif defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
if6_addrlist(TAILQ_FIRST(&ifnet.if_addrhead));
|
||||
nifp = ifnet.if_link.tqe_next;
|
||||
#else
|
||||
if6_addrlist(ifnet.if_addrlist);
|
||||
nifp = ifnet.if_next;
|
||||
#endif
|
||||
|
||||
#ifdef __NetBSD__
|
||||
KREAD(ifnet.if_sadl, &sdl, struct sockaddr_dl);
|
||||
if (sdl.sdl_type == IFT_ETHER) {
|
||||
printf("\tenaddr %s",
|
||||
ether_ntoa((struct ether_addr *)LLADDR(&sdl)));
|
||||
KREAD(ifp, &ec, struct ethercom);
|
||||
printf(" multicnt %d", ec.ec_multicnt);
|
||||
acmc(ec.ec_multiaddrs.lh_first);
|
||||
printf("\n");
|
||||
}
|
||||
#elif defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
/* not supported */
|
||||
#else
|
||||
if (ifnet.if_type == IFT_ETHER) {
|
||||
KREAD(ifp, &arpcom, struct arpcom);
|
||||
printf("\tenaddr %s",
|
||||
ether_ntoa((struct ether_addr *)arpcom.ac_enaddr));
|
||||
KREAD(ifp, &arpcom, struct arpcom);
|
||||
printf(" multicnt %d", arpcom.ac_multicnt);
|
||||
#ifdef __OpenBSD__
|
||||
acmc(arpcom.ac_multiaddrs.lh_first);
|
||||
#else
|
||||
acmc(arpcom.ac_multiaddrs);
|
||||
#endif
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
ifp = nifp;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
char *ifname(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
KREAD(ifp->if_xname, buf, IFNAMSIZ);
|
||||
#else
|
||||
KREAD(ifp->if_name, buf, IFNAMSIZ);
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
|
||||
void kread(addr, buf, len)
|
||||
u_long addr;
|
||||
void *buf;
|
||||
int len;
|
||||
{
|
||||
if (kvm_read(kvmd, addr, buf, len) != len) {
|
||||
perror("kvm_read");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
|
||||
void acmc(am)
|
||||
struct ether_multi *am;
|
||||
{
|
||||
struct ether_multi em;
|
||||
|
||||
while (am) {
|
||||
KREAD(am, &em, struct ether_multi);
|
||||
|
||||
printf("\n\t\t");
|
||||
printf("%s -- ", ether_ntoa((struct ether_addr *)em.enm_addrlo));
|
||||
printf("%s ", ether_ntoa((struct ether_addr *)&em.enm_addrhi));
|
||||
printf("%d", em.enm_refcount);
|
||||
#if !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
am = em.enm_next;
|
||||
#else
|
||||
am = em.enm_list.le_next;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
if6_addrlist(ifap)
|
||||
struct ifaddr *ifap;
|
||||
{
|
||||
static char in6buf[BUFSIZ];
|
||||
struct ifaddr ifa;
|
||||
struct sockaddr sa;
|
||||
struct in6_ifaddr if6a;
|
||||
struct in6_multi *mc = 0;
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
struct ifaddr *ifap0;
|
||||
#endif /* __FreeBSD__ >= 3 */
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
ifap0 = ifap;
|
||||
#endif /* __FreeBSD__ >= 3 */
|
||||
while (ifap) {
|
||||
KREAD(ifap, &ifa, struct ifaddr);
|
||||
if (ifa.ifa_addr == NULL)
|
||||
goto nextifap;
|
||||
KREAD(ifa.ifa_addr, &sa, struct sockaddr);
|
||||
if (sa.sa_family != PF_INET6)
|
||||
goto nextifap;
|
||||
KREAD(ifap, &if6a, struct in6_ifaddr);
|
||||
printf("\tinet6 %s\n",
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&if6a.ia_addr.sin6_addr,
|
||||
in6buf, sizeof(in6buf)));
|
||||
#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
|
||||
mc = mc ? mc : if6a.ia6_multiaddrs.lh_first;
|
||||
#endif
|
||||
nextifap:
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
ifap = ifa.ifa_list.tqe_next;
|
||||
#elif defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
ifap = ifa.ifa_link.tqe_next;
|
||||
#else
|
||||
ifap = ifa.ifa_next;
|
||||
#endif /* __FreeBSD__ >= 3 */
|
||||
}
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
if (ifap0) {
|
||||
struct ifnet ifnet;
|
||||
struct ifmultiaddr ifm, *ifmp = 0;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct in6_multi in6m;
|
||||
struct sockaddr_dl sdl;
|
||||
int in6_multilist_done = 0;
|
||||
|
||||
KREAD(ifap0, &ifa, struct ifaddr);
|
||||
KREAD(ifa.ifa_ifp, &ifnet, struct ifnet);
|
||||
if (ifnet.if_multiaddrs.lh_first)
|
||||
ifmp = ifnet.if_multiaddrs.lh_first;
|
||||
while (ifmp) {
|
||||
KREAD(ifmp, &ifm, struct ifmultiaddr);
|
||||
if (ifm.ifma_addr == NULL)
|
||||
goto nextmulti;
|
||||
KREAD(ifm.ifma_addr, &sa, struct sockaddr);
|
||||
if (sa.sa_family != AF_INET6)
|
||||
goto nextmulti;
|
||||
(void)in6_multientry((struct in6_multi *)
|
||||
ifm.ifma_protospec);
|
||||
if (ifm.ifma_lladdr == 0)
|
||||
goto nextmulti;
|
||||
KREAD(ifm.ifma_lladdr, &sdl, struct sockaddr_dl);
|
||||
printf("\t\t\tmcast-macaddr %s multicnt %d\n",
|
||||
ether_ntoa((struct ether_addr *)LLADDR(&sdl)),
|
||||
ifm.ifma_refcount);
|
||||
nextmulti:
|
||||
ifmp = ifm.ifma_link.le_next;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (mc)
|
||||
in6_multilist(mc);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct in6_multi *
|
||||
in6_multientry(mc)
|
||||
struct in6_multi *mc;
|
||||
{
|
||||
static char mcbuf[BUFSIZ];
|
||||
struct in6_multi multi;
|
||||
|
||||
KREAD(mc, &multi, struct in6_multi);
|
||||
printf("\t\tgroup %s\n", inet_ntop(AF_INET6,
|
||||
(const void *)&multi.in6m_addr,
|
||||
mcbuf, sizeof(mcbuf)));
|
||||
return(multi.in6m_entry.le_next);
|
||||
}
|
||||
|
||||
void
|
||||
in6_multilist(mc)
|
||||
struct in6_multi *mc;
|
||||
{
|
||||
while (mc)
|
||||
mc = in6_multientry(mc);
|
||||
}
|
||||
|
||||
#if !defined(__NetBSD__) && !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(__OpenBSD__)
|
||||
static char *
|
||||
ether_ntoa(e)
|
||||
struct ether_addr *e;
|
||||
{
|
||||
static char buf[20];
|
||||
u_char *p;
|
||||
|
||||
p = (u_char *)e;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
return buf;
|
||||
}
|
||||
#endif
|
12
usr.sbin/prefix/Makefile
Normal file
12
usr.sbin/prefix/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
# From: @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $Id: Makefile,v 1.1.1.1 1999/08/08 23:31:13 itojun Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= prefix
|
||||
SRCS= prefix.c
|
||||
|
||||
MAN8= prefix.8
|
||||
|
||||
CFLAGS+=-DINET6
|
||||
|
||||
.include <bsd.prog.mk>
|
217
usr.sbin/prefix/prefix.8
Normal file
217
usr.sbin/prefix/prefix.8
Normal file
@ -0,0 +1,217 @@
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" 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 project 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 PROJECT 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 PROJECT 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.
|
||||
.\"
|
||||
.\" $Id: prefix.8,v 1.1.1.1 1999/08/08 23:31:13 itojun Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 10, 1998
|
||||
.Dt PREFIX 8
|
||||
.Os KAME
|
||||
.Sh NAME
|
||||
.Nm prefix
|
||||
.Nd configure network interface prefixes
|
||||
.Sh SYNOPSIS
|
||||
.Nm prefix
|
||||
.Ar interface prefix
|
||||
.Op Ar parameters
|
||||
.Op Cm set|delete
|
||||
.Nm prefix
|
||||
.Ar interface
|
||||
.Cm matchpr
|
||||
.Ar match_prefix
|
||||
.Cm mp_len
|
||||
.Ar match_prefix_len
|
||||
.Cm usepr
|
||||
.Ar use_prefix
|
||||
.Cm up_uselen
|
||||
.Ar use_prefix_len
|
||||
.Op Ar parameters
|
||||
.Op Cm add|change|setglobal
|
||||
.Nm prefix
|
||||
.Fl a
|
||||
.Op Fl d
|
||||
.Op Fl u
|
||||
.Cm matchpr
|
||||
.Ar match_prefix
|
||||
.Cm mp_len
|
||||
.Ar match_prefix_len
|
||||
.Cm usepr
|
||||
.Ar use_prefix
|
||||
.Cm up_uselen
|
||||
.Ar use_prefix_uselen
|
||||
.Op Ar parameters
|
||||
.Op Cm add|change|setglobal
|
||||
.Sh DESCRIPTION
|
||||
.Nm Prefix
|
||||
is used to assign an prefix
|
||||
to a network interface and/or renumbering
|
||||
network interface prefixes.
|
||||
.Nm Prefix
|
||||
must be used at boot time to define the network prefix
|
||||
of each interface present on a machine; it may also be used at
|
||||
a later time to renumbering multiple interface's prefixes
|
||||
and other prefix related parameters.
|
||||
.Nm Prefix
|
||||
is router-only command, so you must do following to use it.
|
||||
.Dl % sysctl -w net.inet6.ip6.forwarding=1
|
||||
If net.inet6.ip6.forwarding is set to 0,
|
||||
.Nm Prefix
|
||||
command fails by EPERM error.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Ar interface
|
||||
Specify an
|
||||
.Ar interface
|
||||
for which
|
||||
.Ar prefix
|
||||
is/are assigned or renumbered to.
|
||||
This parameter is a string of the form
|
||||
.Dq name unit ,
|
||||
for example,
|
||||
.Dq en0 .
|
||||
.It Ar prefix
|
||||
Assign/Delete an
|
||||
.Ar prefix
|
||||
to a network interface.
|
||||
.It Cm prefixlen Ar len
|
||||
Specify that
|
||||
.Ar len
|
||||
bits are reserved as identifier for IPv6 sub-networks in
|
||||
.Ar prefix.
|
||||
The
|
||||
.Ar len
|
||||
must be integer, and for syntactical reason it must be between 0 to 128.
|
||||
It is almost always 64 under the current IPv6 assignment rule.
|
||||
If the parameter is ommitted, 64 is used.
|
||||
.It Cm matchpr Ar match_prefix
|
||||
Specify
|
||||
.Ar match_prefix
|
||||
that is used for matching with preassigned prefixes to which
|
||||
.Cm add|change|setglobal
|
||||
command should be applied.
|
||||
.It Cm mp_len Ar match_prefix_len
|
||||
Specify the starting part of
|
||||
.Ar match_prefix
|
||||
to be used for matching with preassigned prefixes, as decimal bit number.
|
||||
.It Cm mp_minlen Ar match_prefix_minlen
|
||||
Specify the minimum length of prefixes which is allowed to be matched to
|
||||
.Ar match_prefix ,
|
||||
as decimal bit number.
|
||||
.Cm add|change|setglobal
|
||||
is not applied to preassigned prefixes with smaller prefix len than
|
||||
.Ar match_prefix_minlen .
|
||||
.It Cm mp_maxlen Ar match_prefix_maxlen
|
||||
Specify the maximum length of prefixes which is allowed to be matched to
|
||||
.Ar match_prefix ,
|
||||
as decimal bit number.
|
||||
.Cm add|change|setglobal
|
||||
is not applied to preassigned prefixes with bigger prefix len than
|
||||
.Ar match_prefix_maxlen .
|
||||
.It Cm usepr Ar use_prefix
|
||||
Specify
|
||||
.Ar use_prefix
|
||||
that is used for prefixes to be added on
|
||||
.Cm add|change|setglobal
|
||||
command.
|
||||
.It Cm up_uselen Ar use_prefix_uselen
|
||||
Specify the starting part of
|
||||
.Ar use_prefix
|
||||
copied to the starting part of prefixes to be added on
|
||||
.Cm add|change|setglobal
|
||||
command, as decimal bit number.
|
||||
.It Cm up_keeplen Ar use_prefix_keeplen
|
||||
Specify the midium part of
|
||||
.Ar use_prefix
|
||||
just next to the starting part specified by
|
||||
.Ar use_prefix_uselen
|
||||
, as decimal bit number.
|
||||
Contiguous bits part in the same bit position of an existent prefix
|
||||
matched with
|
||||
.Ar match_prefix
|
||||
is copied to the same bit position of prefixes to be added.
|
||||
.It Cm pltime Ar time
|
||||
Assign an
|
||||
.Ar time
|
||||
as prefix preferred life time for a prefix to be added.
|
||||
Valid value for
|
||||
.Ar time
|
||||
is decimal seconds number or special format as "d00h00m00s00",
|
||||
where 00 can take any decimal number, and "d" means days, "h" means hours,
|
||||
"m" means minutes, "s" means seconds. And alternatively, special keyword
|
||||
"infinity" can be also be specified.
|
||||
.It Cm vltime Ar time
|
||||
Assign an
|
||||
.Ar time
|
||||
as prefix valid life time for a prefix to be added.
|
||||
Valid value for
|
||||
.Ar time
|
||||
is same as for
|
||||
.Cm pltime.
|
||||
.It Cm raf_auto
|
||||
Enable the autonomous address auto configuration for the prefix to be
|
||||
added.
|
||||
.It Fl raf_auto
|
||||
Disable the autonomous address auto configuration for the prefix to be
|
||||
added.
|
||||
.It Cm raf_onlink
|
||||
Let the prefix to be added to have onlink nature for the assigned
|
||||
interface.
|
||||
.It Fl raf_onlink
|
||||
Let the prefix to be added not to have onlink nature for the assigned
|
||||
interface.
|
||||
.It Cm rrf_decrprefd
|
||||
Enable the decrementation of the pltime.
|
||||
.It Fl rrf_decrprefd
|
||||
Disable the decrementation of the pltime.
|
||||
.It Cm rrf_decrvalid
|
||||
Enable the decrementation of the vltime.
|
||||
.It Fl rrf_decrvalid
|
||||
Disable the decrementation of the vltime.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
Messages indicating the specified interface does not exist, the
|
||||
requested prefix is unknown, or the user is not privileged and
|
||||
tried to alter an interface's configuration.
|
||||
.Sh SEE ALSO
|
||||
M. Crawford,
|
||||
Router Renumbering for IPv6,
|
||||
internet-draft,
|
||||
draft-ietf-ipngwg-router-renum-05.txt
|
||||
.Pp
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr netstat 1 ,
|
||||
.Xr netintro 4 ,
|
||||
.Xr rc 8 ,
|
||||
.Xr routed 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command first appeared in WIDE/KAME IPv6 protocol stack kit.
|
||||
.\"
|
||||
.\" .Sh BUGS
|
||||
.\" (to be written)
|
592
usr.sbin/prefix/prefix.c
Normal file
592
usr.sbin/prefix/prefix.c
Normal file
@ -0,0 +1,592 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
#include <net/if_var.h>
|
||||
#endif /* __FreeBSD__ >= 3 */
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define DEF_ADVVALIDLIFETIME 2592000
|
||||
#define DEF_ADVPREFERREDLIFETIME 604800
|
||||
struct in6_prefixreq prereq = {{NULL}, /* interface name */
|
||||
PR_ORIG_STATIC,
|
||||
64, /* default plen */
|
||||
2592000, /* vltime=30days */
|
||||
604800, /* pltime=7days */
|
||||
/* ra onlink=1 autonomous=1 */
|
||||
{{1,1,0}},
|
||||
{NULL}}; /* prefix */
|
||||
struct in6_rrenumreq rrreq = {{NULL}, /* interface name */
|
||||
PR_ORIG_STATIC, /* default origin */
|
||||
64, /* default match len */
|
||||
0, /* default min match len */
|
||||
128, /* default max match len */
|
||||
0, /* default uselen */
|
||||
0, /* default keeplen */
|
||||
{1,1,0}, /* default raflag mask */
|
||||
2592000, /* vltime=30days */
|
||||
604800, /* pltime=7days */
|
||||
/* ra onlink=1 autonomous=1 */
|
||||
{{1,1,0}},
|
||||
{NULL}, /* match prefix */
|
||||
{NULL} /* use prefix */
|
||||
};
|
||||
|
||||
#define C(x) ((caddr_t) &x)
|
||||
|
||||
struct prefix_cmds {
|
||||
const char *errmsg;
|
||||
int cmd;
|
||||
caddr_t req;
|
||||
} prcmds[] = {
|
||||
{"SIOCSIFPREFIX_IN6 failed", SIOCSIFPREFIX_IN6, C(prereq)},
|
||||
{"SIOCDIFPREFIX_IN6 failed", SIOCDIFPREFIX_IN6, C(prereq)},
|
||||
{"SIOCAIFPREFIX_IN6 failed", SIOCAIFPREFIX_IN6, C(rrreq)},
|
||||
{"SIOCCIFPREFIX_IN6 failed", SIOCCIFPREFIX_IN6, C(rrreq)},
|
||||
{"SIOCSGIFPREFIX_IN6 failed", SIOCSGIFPREFIX_IN6, C(rrreq)}
|
||||
};
|
||||
|
||||
#define PREF_CMD_SET 0
|
||||
#define PREF_CMD_DELETE 1
|
||||
#define PREF_CMD_ADD 2
|
||||
#define PREF_CMD_CHANGE 3
|
||||
#define PREF_CMD_SETGLOBAL 4
|
||||
#define PREF_CMD_MAX 5
|
||||
|
||||
u_int prcmd = PREF_CMD_SET; /* default command */
|
||||
|
||||
char name[32];
|
||||
int flags;
|
||||
|
||||
int newprefix_setdel, newprefix_match, newprefix_use, newprefix_uselen,
|
||||
newprefix_keeplen;
|
||||
|
||||
char ntop_buf[INET6_ADDRSTRLEN]; /*inet_ntop()*/
|
||||
|
||||
void Perror __P((const char *cmd));
|
||||
int prefix __P((int argc, char *const *argv));
|
||||
void usage __P((void));
|
||||
void setlifetime __P((const char *atime, u_int32_t *btime));
|
||||
int all, explicit_prefix = 0;
|
||||
|
||||
typedef void c_func __P((const char *cmd, int arg));
|
||||
c_func set_vltime, set_pltime, set_raf_onlink,
|
||||
set_raf_auto, set_rrf_decrvalid, set_rrf_decrprefd,
|
||||
get_setdelprefix, get_matchprefix, get_useprefix, set_matchlen,
|
||||
set_match_minlen, set_match_maxlen,
|
||||
set_use_uselen, set_use_keeplen, set_prefix_cmd;
|
||||
|
||||
void getprefixlen __P((const char *, int));
|
||||
void getprefix __P((const char *, int));
|
||||
|
||||
#define NEXTARG 0xffffff
|
||||
|
||||
const
|
||||
struct cmd {
|
||||
const char *c_name;
|
||||
int c_parameter; /* NEXTARG means next argv */
|
||||
void (*c_func) __P((const char *, int));
|
||||
} cmds[] = {
|
||||
{ "set", PREF_CMD_SET, set_prefix_cmd },
|
||||
{ "delete", PREF_CMD_DELETE, set_prefix_cmd },
|
||||
{ "prefixlen", NEXTARG, getprefixlen },
|
||||
{ "add", PREF_CMD_ADD, set_prefix_cmd },
|
||||
{ "change", PREF_CMD_CHANGE, set_prefix_cmd },
|
||||
{ "setglobal", PREF_CMD_SETGLOBAL, set_prefix_cmd },
|
||||
{ "matchpr", NEXTARG, get_matchprefix },
|
||||
{ "usepr", NEXTARG, get_useprefix },
|
||||
{ "mp_len", NEXTARG, set_matchlen },
|
||||
{ "mp_minlen", NEXTARG, set_match_minlen },
|
||||
{ "mp_maxlen", NEXTARG, set_match_maxlen },
|
||||
{ "up_uselen", NEXTARG, set_use_uselen },
|
||||
{ "up_keeplen", NEXTARG, set_use_keeplen },
|
||||
{ "vltime", NEXTARG, set_vltime },
|
||||
{ "pltime", NEXTARG, set_pltime },
|
||||
{ "raf_onlink", 1, set_raf_onlink },
|
||||
{ "-raf_onlink", 0, set_raf_onlink },
|
||||
{ "raf_auto", 1, set_raf_auto },
|
||||
{ "-raf_auto", 0, set_raf_auto },
|
||||
{ "rrf_decrvalid", 1, set_rrf_decrvalid },
|
||||
{ "-rrf_decrvalid", 0, set_rrf_decrvalid },
|
||||
{ "rrf_decrprefd", 1, set_rrf_decrprefd },
|
||||
{ "-rrf_decrprefd", 0, set_rrf_decrprefd },
|
||||
{ 0, 0, get_setdelprefix },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "%s",
|
||||
"usage: prefix interface prefix_value [parameters] [set|delete]\n"
|
||||
" prefix interface\n"
|
||||
" matchpr matchpr_value mp_len mp_len_value\n"
|
||||
" usepr usepr_value up_uselen up_uselen_value\n"
|
||||
" [parameters] [add|change|setglobal]\n"
|
||||
" prefix -a [-d] [-u]\n"
|
||||
" matchpr matchpr_value mp_len mp_len_value\n"
|
||||
" usepr usepr_value up_uselen up_uselen_value\n"
|
||||
" [parameters] [add|change|setglobal]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
{
|
||||
int c;
|
||||
int downonly, uponly;
|
||||
int foundit = 0;
|
||||
int addrcount;
|
||||
struct if_msghdr *ifm, *nextifm;
|
||||
struct ifa_msghdr *ifam;
|
||||
struct sockaddr_dl *sdl;
|
||||
char *buf, *lim, *next;
|
||||
|
||||
|
||||
size_t needed;
|
||||
int mib[6];
|
||||
|
||||
/* Parse leading line options */
|
||||
all = downonly = uponly = 0;
|
||||
while ((c = getopt(argc, argv, "adu")) != -1) {
|
||||
switch (c) {
|
||||
case 'a': /* scan all interfaces */
|
||||
all++;
|
||||
break;
|
||||
case 'd': /* restrict scan to "down" interfaces */
|
||||
downonly++;
|
||||
break;
|
||||
case 'u': /* restrict scan to "up" interfaces */
|
||||
uponly++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* nonsense.. */
|
||||
if (uponly && downonly)
|
||||
usage();
|
||||
|
||||
if (!all) {
|
||||
/* not listing, need an argument */
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
strncpy(name, *argv, sizeof(name));
|
||||
argc--, argv++;
|
||||
}
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[2] = 0;
|
||||
mib[3] = AF_INET6; /* address family */
|
||||
mib[4] = NET_RT_IFLIST;
|
||||
mib[5] = 0;
|
||||
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
|
||||
errx(1, "iflist-sysctl-estimate");
|
||||
if ((buf = malloc(needed)) == NULL)
|
||||
errx(1, "malloc");
|
||||
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
|
||||
errx(1, "actual retrieval of interface table");
|
||||
lim = buf + needed;
|
||||
|
||||
next = buf;
|
||||
while (next < lim) {
|
||||
|
||||
ifm = (struct if_msghdr *)next;
|
||||
|
||||
if (ifm->ifm_type == RTM_IFINFO) {
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
flags = ifm->ifm_flags;
|
||||
} else {
|
||||
fprintf(stderr, "out of sync parsing NET_RT_IFLIST\n");
|
||||
fprintf(stderr, "expected %d, got %d\n", RTM_IFINFO,
|
||||
ifm->ifm_type);
|
||||
fprintf(stderr, "msglen = %d\n", ifm->ifm_msglen);
|
||||
fprintf(stderr, "buf:%p, next:%p, lim:%p\n", buf, next,
|
||||
lim);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
next += ifm->ifm_msglen;
|
||||
ifam = NULL;
|
||||
addrcount = 0;
|
||||
while (next < lim) {
|
||||
|
||||
nextifm = (struct if_msghdr *)next;
|
||||
|
||||
if (nextifm->ifm_type != RTM_NEWADDR)
|
||||
break;
|
||||
|
||||
if (ifam == NULL)
|
||||
ifam = (struct ifa_msghdr *)nextifm;
|
||||
|
||||
addrcount++;
|
||||
next += nextifm->ifm_msglen;
|
||||
}
|
||||
|
||||
if (all) {
|
||||
if (uponly)
|
||||
if ((flags & IFF_UP) == 0)
|
||||
continue; /* not up */
|
||||
if (downonly)
|
||||
if (flags & IFF_UP)
|
||||
continue; /* not down */
|
||||
strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
|
||||
name[sdl->sdl_nlen] = '\0';
|
||||
} else {
|
||||
if (strlen(name) != sdl->sdl_nlen)
|
||||
continue; /* not same len */
|
||||
if (strncmp(name, sdl->sdl_data, sdl->sdl_nlen) != 0)
|
||||
continue; /* not same name */
|
||||
}
|
||||
|
||||
if (argc > 0)
|
||||
prefix(argc, argv);
|
||||
#if 0
|
||||
else {
|
||||
/* TODO: print prefix status by sysctl */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (all == 0) {
|
||||
foundit++; /* flag it as 'done' */
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
|
||||
if (all == 0 && foundit == 0)
|
||||
errx(1, "interface %s does not exist", name);
|
||||
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
prefix(int argc, char *const *argv)
|
||||
{
|
||||
int s;
|
||||
|
||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
|
||||
err(1, "socket");
|
||||
|
||||
while (argc > 0) {
|
||||
register const struct cmd *p;
|
||||
|
||||
for (p = cmds; p->c_name; p++)
|
||||
if (strcmp(*argv, p->c_name) == 0)
|
||||
break;
|
||||
if (p->c_func) {
|
||||
if (p->c_parameter == NEXTARG) {
|
||||
if (argv[1] == NULL)
|
||||
errx(1, "'%s' requires argument",
|
||||
p->c_name);
|
||||
(*p->c_func)(argv[1], 0);
|
||||
argc--, argv++;
|
||||
} else
|
||||
(*p->c_func)(*argv, p->c_parameter);
|
||||
}
|
||||
argc--, argv++;
|
||||
}
|
||||
if (prcmd > PREF_CMD_MAX) {
|
||||
Perror("ioctl: unknown prefix cmd");
|
||||
goto end;
|
||||
}
|
||||
if (prcmd == PREF_CMD_SET || prcmd == PREF_CMD_DELETE) {
|
||||
if (!newprefix_setdel)
|
||||
usage();
|
||||
} else { /* ADD|CHANGE|SETGLOBAL */
|
||||
if (!newprefix_match)
|
||||
usage();
|
||||
}
|
||||
if (!newprefix_use)
|
||||
rrreq.irr_u_uselen = 0; /* make clear that no use_prefix */
|
||||
else if (newprefix_keeplen == NULL && rrreq.irr_u_uselen < 64)
|
||||
/* init keeplen to make uselen + keeplen equal 64 */
|
||||
rrreq.irr_u_keeplen = 64 - rrreq.irr_u_uselen;
|
||||
if (explicit_prefix == 0) {
|
||||
/* Aggregatable address architecture defines all prefixes
|
||||
are 64. So, it is convenient to set prefixlen to 64 if
|
||||
it is not specified. */
|
||||
getprefixlen("64", 0);
|
||||
}
|
||||
strncpy(prcmds[prcmd].req, name, IFNAMSIZ);
|
||||
if (ioctl(s, prcmds[prcmd].cmd, prcmds[prcmd].req) < 0) {
|
||||
if (all && errno == EADDRNOTAVAIL)
|
||||
goto end;
|
||||
Perror(prcmds[prcmd].errmsg);
|
||||
}
|
||||
end:
|
||||
close(s);
|
||||
return(0);
|
||||
}
|
||||
#define PREFIX 0
|
||||
#define MPREFIX 1
|
||||
#define UPREFIX 2
|
||||
|
||||
void
|
||||
Perror(cmd)
|
||||
const char *cmd;
|
||||
{
|
||||
switch (errno) {
|
||||
|
||||
case ENXIO:
|
||||
errx(1, "%s: no such interface", cmd);
|
||||
break;
|
||||
|
||||
case EPERM:
|
||||
errx(1, "%s: permission denied", cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
err(1, "%s", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
#define SIN6(x) ((struct sockaddr_in6 *) &(x))
|
||||
struct sockaddr_in6 *sin6tab[] = {
|
||||
SIN6(prereq.ipr_prefix), SIN6(rrreq.irr_matchprefix),
|
||||
SIN6(rrreq.irr_useprefix)};
|
||||
|
||||
void
|
||||
getprefixlen(const char *plen, int unused)
|
||||
{
|
||||
int len = atoi(plen);
|
||||
|
||||
if ((len < 0) || (len > 128))
|
||||
errx(1, "%s: bad value", plen);
|
||||
|
||||
/* set plen for prereq */
|
||||
prereq.ipr_plen = len;
|
||||
explicit_prefix = 1;
|
||||
}
|
||||
|
||||
void
|
||||
getprefix(const char *prefix, int which)
|
||||
{
|
||||
register struct sockaddr_in6 *sin = sin6tab[which];
|
||||
|
||||
/*
|
||||
* Delay the ioctl to set the interface prefix until flags are all set.
|
||||
* The prefix interpretation may depend on the flags,
|
||||
* and the flags may change when the prefix is set.
|
||||
*/
|
||||
|
||||
sin->sin6_len = sizeof(*sin);
|
||||
sin->sin6_family = AF_INET6;
|
||||
|
||||
if (inet_pton(AF_INET6, prefix, &sin->sin6_addr) != 1)
|
||||
errx(1, "%s: bad value", prefix);
|
||||
}
|
||||
|
||||
void
|
||||
get_setdelprefix(const char *prefix, int unused)
|
||||
{
|
||||
newprefix_setdel++;
|
||||
getprefix(prefix, PREFIX);
|
||||
}
|
||||
|
||||
void
|
||||
get_matchprefix(const char *prefix, int unused)
|
||||
{
|
||||
newprefix_match++;
|
||||
prcmd = (prcmd == PREF_CMD_SET) ? PREF_CMD_ADD : prcmd;
|
||||
getprefix(prefix, MPREFIX);
|
||||
}
|
||||
|
||||
void
|
||||
get_useprefix(const char *prefix, int unused)
|
||||
{
|
||||
newprefix_use++;
|
||||
if (newprefix_uselen == 0)
|
||||
rrreq.irr_u_uselen = 64;
|
||||
getprefix(prefix, UPREFIX);
|
||||
}
|
||||
|
||||
static int
|
||||
get_plen(const char *plen)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = atoi(plen);
|
||||
if ((len < 0) || (len > 128))
|
||||
errx(1, "%s: bad value", plen);
|
||||
return len;
|
||||
}
|
||||
|
||||
void
|
||||
set_matchlen(const char *plen, int unused)
|
||||
{
|
||||
rrreq.irr_m_len = get_plen(plen);
|
||||
}
|
||||
|
||||
void
|
||||
set_match_minlen(const char *plen, int unused)
|
||||
{
|
||||
rrreq.irr_m_minlen = get_plen(plen);
|
||||
}
|
||||
|
||||
void
|
||||
set_match_maxlen(const char *plen, int unused)
|
||||
{
|
||||
rrreq.irr_m_maxlen = get_plen(plen);
|
||||
}
|
||||
|
||||
void
|
||||
set_use_uselen(const char *plen, int unused)
|
||||
{
|
||||
newprefix_uselen++;
|
||||
rrreq.irr_u_uselen = get_plen(plen);
|
||||
}
|
||||
|
||||
void
|
||||
set_use_keeplen(const char *plen, int unused)
|
||||
{
|
||||
newprefix_keeplen++;
|
||||
rrreq.irr_u_keeplen = get_plen(plen);
|
||||
}
|
||||
|
||||
void
|
||||
set_vltime(const char *ltime, int unused)
|
||||
{
|
||||
setlifetime(ltime, &prereq.ipr_vltime);
|
||||
rrreq.irr_vltime = prereq.ipr_vltime;
|
||||
}
|
||||
|
||||
void
|
||||
set_pltime(const char *ltime, int unused)
|
||||
{
|
||||
setlifetime(ltime, &prereq.ipr_pltime);
|
||||
rrreq.irr_pltime = prereq.ipr_pltime;
|
||||
}
|
||||
|
||||
void
|
||||
set_raf_onlink(const char *unused, int value)
|
||||
{
|
||||
/* raflagmask is only meaningful when newprefix_rrenum */
|
||||
rrreq.irr_raflagmask.onlink = 1;
|
||||
prereq.ipr_flags.prf_ra.onlink =
|
||||
rrreq.irr_flags.prf_ra.onlink = value ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_raf_auto(const char *unused, int value)
|
||||
{
|
||||
/* only meaningful when newprefix_rrenum */
|
||||
rrreq.irr_raflagmask.autonomous = 1;
|
||||
prereq.ipr_flags.prf_ra.autonomous =
|
||||
rrreq.irr_flags.prf_ra.autonomous = value ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_rrf_decrvalid(const char *unused, int value)
|
||||
{
|
||||
prereq.ipr_flags.prf_rr.decrvalid =
|
||||
rrreq.irr_flags.prf_rr.decrvalid = value ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_rrf_decrprefd(const char *unused, int value)
|
||||
{
|
||||
prereq.ipr_flags.prf_rr.decrprefd =
|
||||
rrreq.irr_flags.prf_rr.decrprefd = value ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_prefix_cmd(const char *unused, int cmd)
|
||||
{
|
||||
prcmd = cmd;
|
||||
}
|
||||
|
||||
void
|
||||
setlifetime(const char *atime, u_int32_t *btime)
|
||||
{
|
||||
int days = 0, hours = 0, minutes = 0, seconds = 0;
|
||||
u_int32_t ttime;
|
||||
char *check;
|
||||
|
||||
if (strcmp(atime, "infinity") == 0) {
|
||||
*btime = 0xffffffff;
|
||||
return;
|
||||
}
|
||||
ttime = strtoul(atime, &check ,10) & 0xffffffff;
|
||||
if (*check == '\0') {
|
||||
*btime = ttime;
|
||||
return;
|
||||
}
|
||||
if (sscanf(atime, "d%2dh%2dm%2ds%2d", &days, &hours, &minutes,
|
||||
&seconds) < 0) {
|
||||
Perror("wrong time format: valid is d00h00m00s00, \n"
|
||||
"where 00 can be any octal number, \n"
|
||||
"\'d\' is for days, \'h\' is for hours, \n"
|
||||
"\'m\' is for minutes, and \'s\' is for seconds \n");
|
||||
return;
|
||||
}
|
||||
*btime = 0;
|
||||
*btime += seconds;
|
||||
*btime += minutes * 60;
|
||||
*btime += hours * 3600;
|
||||
*btime += days * 86400;
|
||||
return;
|
||||
}
|
9
usr.sbin/rip6query/Makefile
Normal file
9
usr.sbin/rip6query/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= rip6query
|
||||
MAN8= rip6query.8
|
||||
|
||||
CFLAGS+=-DINET6 -I${.CURDIR}/../route6d
|
||||
|
||||
.include <bsd.prog.mk>
|
62
usr.sbin/rip6query/rip6query.8
Normal file
62
usr.sbin/rip6query/rip6query.8
Normal file
@ -0,0 +1,62 @@
|
||||
.\"
|
||||
.\" Copyright (C) 1998 and 1999 WIDE Project.
|
||||
.\" 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 project 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 PROJECT 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 PROJECT 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.
|
||||
.\"
|
||||
.\" $Id: rip6query.8,v 1.1 1999/10/07 05:36:36 itojun Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd Oct 7, 1999
|
||||
.Dt RIP6QUERY 8
|
||||
.Os KAME
|
||||
.Sh NAME
|
||||
.Nm rip6query
|
||||
.Nd RIPng debugging tool
|
||||
.\"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl I Ar interface
|
||||
.Ar destination
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
requests remote RIPng daemon on
|
||||
.Ar destionation
|
||||
to dump RIPng routing information.
|
||||
.Fl I
|
||||
lets you specify outgoing
|
||||
.Ar interface
|
||||
for the query packet,
|
||||
and is useful when link-local address is specified for
|
||||
.Ar destination .
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr route6d 8 .
|
||||
.\"
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command first appeared in WIDE Hydrangea IPv6 protocol stack kit.
|
206
usr.sbin/rip6query/rip6query.c
Normal file
206
usr.sbin/rip6query/rip6query.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <err.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
#include <net/if_var.h>
|
||||
#endif /* __FreeBSD__ >= 3 */
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "route6d.h"
|
||||
|
||||
/* wrapper for KAME-special getnameinfo() */
|
||||
#ifndef NI_WITHSCOPEID
|
||||
#define NI_WITHSCOPEID 0
|
||||
#endif
|
||||
|
||||
int s;
|
||||
extern int errno;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct rip6 *ripbuf;
|
||||
|
||||
#define RIPSIZE(n) (sizeof(struct rip6) + (n-1) * sizeof(struct netinfo6))
|
||||
|
||||
int main __P((int, char **));
|
||||
static void usage __P((void));
|
||||
static const char *sa_n2a __P((struct sockaddr *));
|
||||
static const char *inet6_n2a __P((struct in6_addr *));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
struct netinfo6 *np;
|
||||
struct sockaddr_in6 fsock;
|
||||
int i, n, len, flen;
|
||||
int c;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
int ifidx = -1;
|
||||
int error;
|
||||
char pbuf[10];
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
while ((c = getopt(argc, argv, "I:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'I':
|
||||
ifidx = if_nametoindex(optarg);
|
||||
if (ifidx == 0) {
|
||||
errx(1, "invalid interface %s", optarg);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc != 1) {
|
||||
usage();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
||||
err(1, "socket");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* getaddrinfo is preferred for addr@ifname syntax */
|
||||
snprintf(pbuf, sizeof(pbuf), "%d", RIP6_PORT);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET6;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
error = getaddrinfo(argv[0], pbuf, &hints, &res);
|
||||
if (error) {
|
||||
errx(1, "%s: %s", argv[0], gai_strerror(error));
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (res->ai_next) {
|
||||
errx(1, "%s: %s", argv[0], "resolved to multiple addrs");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (sizeof(sin6) != res->ai_addrlen) {
|
||||
errx(1, "%s: %s", argv[0], "invalid addrlen");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
memcpy(&sin6, res->ai_addr, res->ai_addrlen);
|
||||
if (ifidx >= 0)
|
||||
sin6.sin6_scope_id = ifidx;
|
||||
|
||||
if ((ripbuf = (struct rip6 *)malloc(BUFSIZ)) == NULL) {
|
||||
err(1, "malloc");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
ripbuf->rip6_cmd = RIP6_REQUEST;
|
||||
ripbuf->rip6_vers = RIP6_VERSION;
|
||||
ripbuf->rip6_res1[0] = 0;
|
||||
ripbuf->rip6_res1[1] = 0;
|
||||
np = ripbuf->rip6_nets;
|
||||
bzero(&np->rip6_dest, sizeof(struct in6_addr));
|
||||
np->rip6_tag = 0;
|
||||
np->rip6_plen = 0;
|
||||
np->rip6_metric = HOPCNT_INFINITY6;
|
||||
if (sendto(s, ripbuf, RIPSIZE(1), 0, (struct sockaddr *)&sin6,
|
||||
sizeof(struct sockaddr_in6)) < 0) {
|
||||
err(1, "send");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
do {
|
||||
flen = sizeof(fsock);
|
||||
if ((len = recvfrom(s, ripbuf, BUFSIZ, 0,
|
||||
(struct sockaddr *)&fsock, &flen)) < 0) {
|
||||
err(1, "recvfrom");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
printf("Response from %s len %d\n",
|
||||
sa_n2a((struct sockaddr *)&fsock), len);
|
||||
n = (len - sizeof(struct rip6) + sizeof(struct netinfo6)) /
|
||||
sizeof(struct netinfo6);
|
||||
np = ripbuf->rip6_nets;
|
||||
for (i = 0; i < n; i++, np++) {
|
||||
printf("\t%s/%d [%d]", inet6_n2a(&np->rip6_dest),
|
||||
np->rip6_plen, np->rip6_metric);
|
||||
if (np->rip6_tag)
|
||||
printf(" tag=0x%x", ntohs(np->rip6_tag));
|
||||
printf("\n");
|
||||
}
|
||||
} while (len == RIPSIZE(24));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: rip6query [-I iface] address\n");
|
||||
}
|
||||
|
||||
/* getnameinfo() is preferred as we may be able to show ifindex as ifname */
|
||||
static const char *
|
||||
sa_n2a(sa)
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
|
||||
if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf),
|
||||
NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) != 0) {
|
||||
snprintf(buf, sizeof(buf), "%s", "(invalid)");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char *
|
||||
inet6_n2a(addr)
|
||||
struct in6_addr *addr;
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
|
||||
return inet_ntop(AF_INET6, addr, buf, sizeof(buf));
|
||||
}
|
9
usr.sbin/route6d/Makefile
Normal file
9
usr.sbin/route6d/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= route6d
|
||||
MAN8= route6d.8
|
||||
|
||||
CFLAGS+= -Dss_len=__ss_len -Dss_family=__ss_family -DADVAPI -DINET6
|
||||
|
||||
.include <bsd.prog.mk>
|
64
usr.sbin/route6d/misc/chkrt
Executable file
64
usr.sbin/route6d/misc/chkrt
Executable file
@ -0,0 +1,64 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
$dump="/var/tmp/route6d_dump";
|
||||
$pidfile="/var/run/route6d.pid";
|
||||
|
||||
system("rm -f $dump");
|
||||
|
||||
open(FD, "< $pidfile") || die "Can not open $pidfile";
|
||||
$_ = <FD>;
|
||||
chop;
|
||||
close(FD);
|
||||
system("kill -INT $_");
|
||||
|
||||
open(NS, "/usr/local/v6/bin/netstat -r -n|") || die "Can not open netstat";
|
||||
while (<NS>) {
|
||||
chop;
|
||||
next unless (/^3f/ || /^5f/);
|
||||
@f = split(/\s+/);
|
||||
$gw{$f[0]} = $f[1];
|
||||
$int{$f[0]} = $f[3];
|
||||
}
|
||||
close(NS);
|
||||
|
||||
$err=0;
|
||||
sleep(2);
|
||||
open(FD, "< $dump") || die "Can not open $dump";
|
||||
while (<FD>) {
|
||||
chop;
|
||||
next unless (/^ 3f/ || /^ 5f/);
|
||||
@f = split(/\s+/);
|
||||
$dst = $f[1];
|
||||
$f[2] =~ /if\(\d:([a-z0-9]+)\)/;
|
||||
$intf = $1;
|
||||
$f[3] =~ /gw\(([a-z0-9:]+)\)/;
|
||||
$gateway = $1;
|
||||
$f[4] =~ /\[(\d+)\]/;
|
||||
$metric = $1;
|
||||
$f[5] =~ /age\((\d+)\)/;
|
||||
$age = $1;
|
||||
unless (defined($gw{$dst})) {
|
||||
print "NOT FOUND: $dst $intf $gateway $metric $age\n";
|
||||
$err++;
|
||||
next;
|
||||
}
|
||||
if ($gw{$dst} ne $gateway && $gw{$dst} !~ /link#\d+/) {
|
||||
print "WRONG GW: $dst $intf $gateway $metric $age\n";
|
||||
print "kernel gw: $gw{$dst}\n";
|
||||
$err++;
|
||||
next;
|
||||
}
|
||||
if ($int{$dst} ne $intf) {
|
||||
print "WRONG IF: $dst $intf $gateway $metric $age\n";
|
||||
print "kernel if: $int{$dst}\n";
|
||||
$err++;
|
||||
next;
|
||||
}
|
||||
}
|
||||
close(FD);
|
||||
|
||||
if ($err == 0) {
|
||||
print "No error found\n";
|
||||
}
|
52
usr.sbin/route6d/misc/cksum.c
Normal file
52
usr.sbin/route6d/misc/cksum.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned short buf[BUFSIZ];
|
||||
|
||||
main()
|
||||
{
|
||||
int i;
|
||||
unsigned short *p = buf, *q = &buf[4];
|
||||
unsigned long sum, sum2;
|
||||
|
||||
while (scanf("%x", &i) != EOF) {
|
||||
*p++ = i; printf("%d ", i);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
sum = buf[2] + (buf[3] >> 8) & 0xff;
|
||||
while (q != p)
|
||||
sum += (*q++ & 0xffff);
|
||||
sum2 = (sum & 0xffff) + (sum >> 16) & 0xffff;
|
||||
printf("%x, %x\n", sum, sum2);
|
||||
}
|
234
usr.sbin/route6d/route6d.8
Normal file
234
usr.sbin/route6d/route6d.8
Normal file
@ -0,0 +1,234 @@
|
||||
.\" Copyright (c) 1996 WIDE Project. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modifications, are permitted provided that the above copyright notice
|
||||
.\" and this paragraph are duplicated in all such forms and that any
|
||||
.\" documentation, advertising materials, and other materials related to
|
||||
.\" such distribution and use acknowledge that the software was developed
|
||||
.\" by the WIDE Project, Japan. The name of the Project may not be used to
|
||||
.\" endorse or promote products derived from this software without
|
||||
.\" specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
|
||||
.\" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
.\" LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
.\" A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 31, 1997
|
||||
.Dt ROUTE6D 8
|
||||
.Os KAME
|
||||
.Sh NAME
|
||||
.Nm route6d
|
||||
.Nd RIP6 Routing Daemon
|
||||
.Sh SYNOPSIS
|
||||
.Nm route6d
|
||||
.Op Fl adDhlqsS
|
||||
.Op Fl R Ar routelog
|
||||
.Op Fl A Ar prefix/preflen,if1[,if2...]
|
||||
.Op Fl L Ar prefix/preflen,if1[,if2...]
|
||||
.Op Fl N Ar if1[,if2...]
|
||||
.Op Fl O Ar prefix/preflen,if1[,if2...]
|
||||
.Op Fl T Ar if1[,if2...]
|
||||
.Op Fl t Ar tag
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
is a routing daemon which supports RIP over IPv6.
|
||||
.Pp
|
||||
Options are:
|
||||
.Bl -tag -width indent
|
||||
.\"
|
||||
.It Fl a
|
||||
Enables aging of the statically defined routes.
|
||||
With this option, any
|
||||
statically defined routes will be removed unless corresponding updates
|
||||
arrive as if the routes are received at the startup of
|
||||
.Nm route6d .
|
||||
.\"
|
||||
.It Fl R Ar routelog
|
||||
This option makes the
|
||||
.Nm
|
||||
to log the route change (add/delete) to the file
|
||||
.Ar routelog .
|
||||
.\"
|
||||
.It Fl A Ar prefix/preflen,if1[,if2...]
|
||||
This option is used for aggregating routes.
|
||||
.Ar prefix/preflen
|
||||
specifies the prefix and the prefix length of the
|
||||
aggregated route.
|
||||
When advertising routes,
|
||||
.Nm
|
||||
filters specific routes covered by the aggregate,
|
||||
and advertises the aggregated route
|
||||
.Ar prefix/preflen ,
|
||||
to the interfaces specified in the comma-separated interface list,
|
||||
.Ar if1[,if2...] .
|
||||
.Nm
|
||||
creates a static route to
|
||||
.Ar prefix/preflen
|
||||
with
|
||||
.Dv RTF_REJECT
|
||||
flag, into the kernel routing table.
|
||||
.\"
|
||||
.It Fl d
|
||||
Enables output of debugging message.
|
||||
This option also instructs
|
||||
.Nm
|
||||
to run in foreground mode
|
||||
.Pq does not become daemon .
|
||||
.\"
|
||||
.It Fl D
|
||||
Enables extensive output of debugging message.
|
||||
This option also instructs
|
||||
.Nm
|
||||
to run in foreground mode
|
||||
.Pq does not become daemon .
|
||||
.\"
|
||||
.It Fl h
|
||||
Disables the split horizon processing.
|
||||
.\"
|
||||
.It Fl l
|
||||
By default,
|
||||
.Nm
|
||||
will not exchange site local routes for safety reasons.
|
||||
This is because semantics of site local address space is rather vague,
|
||||
and there is no good way to define site local boundary.
|
||||
With
|
||||
.Fl l
|
||||
option,
|
||||
.Nm
|
||||
will exchange site local routes as well.
|
||||
It must not be used on site boundary routers,
|
||||
since
|
||||
.Fl l
|
||||
option assumes that all interfaces are in the same site.
|
||||
.\"
|
||||
.It Fl L Ar prefix/preflen,if1[,if2...]
|
||||
Filter incoming routes from interfaces
|
||||
.Ar if1,[if2...] .
|
||||
.Nm
|
||||
will accept incoming routes that are in
|
||||
.Ar prefix/preflen .
|
||||
If multiple
|
||||
.Fl L
|
||||
options are specified, any routes that match one of the options is accepted.
|
||||
.Li ::/0
|
||||
is treated specially as default route, not
|
||||
.Do
|
||||
any route that has longer prefix length than, or equal to 0
|
||||
.Dc .
|
||||
If you would like to accept any route, specify no
|
||||
.Fl L
|
||||
option.
|
||||
For example, with
|
||||
.Do
|
||||
.Fl L
|
||||
.Li 3ffe::/16,if1
|
||||
.Fl L
|
||||
.Li ::/0,if1
|
||||
.Dc
|
||||
.Nm
|
||||
will accept default route and routes in 6bone test address, but no others.
|
||||
.\"
|
||||
.It Fl N Ar if1[,if2...]
|
||||
Do not listen to, or advertise, route from/to interfaces specified by
|
||||
.Ar if1,[if2...] .
|
||||
.\"
|
||||
.It Fl O Ar prefix/preflen,if1[,if2...]
|
||||
Restrict route advertisement toward interfaces specified by
|
||||
.Ar if1,[if2...] .
|
||||
With this option
|
||||
.Nm
|
||||
will only advertise routes that matches
|
||||
.Ar prefix/preflen .
|
||||
.\"
|
||||
.It Fl q
|
||||
Makes
|
||||
.Nm
|
||||
in listen-only mode.
|
||||
No advertisement is sent.
|
||||
.\"
|
||||
.It Fl s
|
||||
Makes
|
||||
.Nm
|
||||
to advertise the statically defined routes which exist in the kernel routing
|
||||
table when
|
||||
.Nm
|
||||
invoked.
|
||||
Announcements obey the regular split horizon rule.
|
||||
.\"
|
||||
.It Fl S
|
||||
This option is the same as
|
||||
.Fl s
|
||||
option except that no split horizon rule does apply.
|
||||
.\"
|
||||
.It Fl T Ar if1[,if2...]
|
||||
Advertise only default route, toward
|
||||
.Ar if1,[if2...] .
|
||||
.\"
|
||||
.It Fl t Ar tag
|
||||
Attach route tag
|
||||
.Ar tag
|
||||
to originated route entries.
|
||||
.Ar tag
|
||||
can be decimal, octal prefixed by
|
||||
.Li 0 ,
|
||||
or hexadecimal prefixed by
|
||||
.Li 0x .
|
||||
.\"
|
||||
.El
|
||||
.Pp
|
||||
Upon receipt of signal
|
||||
.Dv SIGINT
|
||||
or
|
||||
.Dv SIGUSR1 ,
|
||||
.Nm
|
||||
will dump the current internal state into
|
||||
.Pa /var/tmp/route6d_dump .
|
||||
.\"
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/tmp/route6d_dump -compact
|
||||
.It Pa /var/tmp/route6d_dump
|
||||
dumps internal state on
|
||||
.Dv SIGINT
|
||||
or
|
||||
.Dv SIGUSR1
|
||||
.El
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Rs
|
||||
.%A G. Malkin
|
||||
.%A R. Minnear
|
||||
.%T RIPng for IPv6
|
||||
.%R RFC2080
|
||||
.%D January 1997
|
||||
.Re
|
||||
.\"
|
||||
.Sh NOTE
|
||||
.Nm Route6d
|
||||
uses IPv6 advanced API,
|
||||
defined in RFC2292,
|
||||
for communicating with peers using link-local addresses.
|
||||
.Pp
|
||||
Internally
|
||||
.Nm
|
||||
embeds interface identifier into bit 32 to 63 of link-local addresses
|
||||
.Po
|
||||
.Li fe80::xx
|
||||
and
|
||||
.Li ff02::xx
|
||||
.Pc
|
||||
so they will be visible on internal state dump file
|
||||
.Pq Pa /var/tmp/route6d_dump .
|
||||
.Pp
|
||||
Routing table manipulation differs from IPv6 implementation to implementation.
|
||||
Currently
|
||||
.Nm
|
||||
obeys WIDE Hydrangea/KAME IPv6 kernel,
|
||||
and will not be able to run on other platforms.
|
||||
.Pp
|
||||
Current
|
||||
.Nm
|
||||
does not reduce the rate of the triggered updates when consecutive updates
|
||||
arrive.
|
2913
usr.sbin/route6d/route6d.c
Normal file
2913
usr.sbin/route6d/route6d.c
Normal file
File diff suppressed because it is too large
Load Diff
91
usr.sbin/route6d/route6d.h
Normal file
91
usr.sbin/route6d/route6d.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* $Header: /cvsroot/kame/kame/kame/kame/route6d/route6d.h,v 1.1.1.1 1999/08/08 23:31:35 itojun Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* not yet in use
|
||||
#define ROUTE6D_CONF "/usr/local/v6/etc/route6d.conf"
|
||||
*/
|
||||
|
||||
#define ROUTE6D_DUMP "/var/tmp/route6d_dump"
|
||||
#define ROUTE6D_PID "/var/run/route6d.pid"
|
||||
|
||||
#define RIP6_VERSION 1
|
||||
|
||||
#define RIP6_REQUEST 1
|
||||
#define RIP6_RESPONSE 2
|
||||
|
||||
struct netinfo6 {
|
||||
struct in6_addr rip6_dest;
|
||||
u_short rip6_tag;
|
||||
u_char rip6_plen;
|
||||
u_char rip6_metric;
|
||||
};
|
||||
|
||||
struct rip6 {
|
||||
u_char rip6_cmd;
|
||||
u_char rip6_vers;
|
||||
u_char rip6_res1[2];
|
||||
union {
|
||||
struct netinfo6 ru6_nets[1];
|
||||
char ru6_tracefile[1];
|
||||
} rip6un;
|
||||
#define rip6_nets rip6un.ru6_nets
|
||||
#define rip6_tracefile rip6un.ru6_tracefile
|
||||
};
|
||||
|
||||
#define HOPCNT_INFINITY6 16
|
||||
#define NEXTHOP_METRIC 0xff
|
||||
#define RIP6_MAXMTU 1500
|
||||
|
||||
#define IFMINMTU 576
|
||||
|
||||
#ifndef DEBUG
|
||||
#define SUPPLY_INTERVAL6 30
|
||||
#define RIP_LIFETIME 180
|
||||
#define RIP_HOLDDOWN 120
|
||||
#define RIP_TRIG_INT6_MAX 5
|
||||
#define RIP_TRIG_INT6_MIN 1
|
||||
#else
|
||||
/* only for debugging; can not wait for 30sec to appear a bug */
|
||||
#define SUPPLY_INTERVAL6 10
|
||||
#define RIP_LIFETIME 60
|
||||
#define RIP_HOLDDOWN 40
|
||||
#define RIP_TRIG_INT6_MAX 5
|
||||
#define RIP_TRIG_INT6_MIN 1
|
||||
#endif
|
||||
|
||||
#define RIP6_PORT 521
|
||||
#define RIP6_DEST "ff02::9"
|
||||
|
||||
#define LOOPBACK_IF "lo0"
|
25
usr.sbin/rtsold/Makefile
Normal file
25
usr.sbin/rtsold/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# Copyright (c) 1996 WIDE Project. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modifications, are permitted provided that the above copyright notice
|
||||
# and this paragraph are duplicated in all such forms and that any
|
||||
# documentation, advertising materials, and other materials related to
|
||||
# such distribution and use acknowledge that the software was developed
|
||||
# by the WIDE Project, Japan. The name of the Project may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
|
||||
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE.
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= rtsold
|
||||
SRCS= rtsold.c rtsol.c if.c probe.c dump.c
|
||||
CFLAGS+=-DINET6
|
||||
LDADD+= -lkvm
|
||||
DPADD+= ${LIBKVM}
|
||||
|
||||
MAN8= rtsold.8
|
||||
MLINKS= rtsold.8 rtsol.8
|
||||
|
||||
.include <bsd.prog.mk>
|
137
usr.sbin/rtsold/dump.c
Normal file
137
usr.sbin/rtsold/dump.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 1999 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "rtsold.h"
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
extern struct ifinfo *iflist;
|
||||
|
||||
static char *sec2str __P((time_t));
|
||||
char *ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"};
|
||||
|
||||
static void
|
||||
dump_interface_status()
|
||||
{
|
||||
struct ifinfo *ifinfo;
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
for (ifinfo = iflist; ifinfo; ifinfo = ifinfo->next) {
|
||||
fprintf(fp, "Interface %s\n", ifinfo->ifname);
|
||||
fprintf(fp, " probe interval: ");
|
||||
if (ifinfo->probeinterval) {
|
||||
fprintf(fp, "%d\n", ifinfo->probeinterval);
|
||||
fprintf(fp, " probe timer: %d\n", ifinfo->probetimer);
|
||||
}
|
||||
else {
|
||||
fprintf(fp, "infinity\n");
|
||||
fprintf(fp, " no probe timer\n");
|
||||
}
|
||||
fprintf(fp, " interface status: %s\n",
|
||||
ifinfo->active > 0 ? "active" : "inactive");
|
||||
fprintf(fp, " rtsold status: %s\n", ifstatstr[ifinfo->state]);
|
||||
fprintf(fp, " carrier detection: %s\n",
|
||||
ifinfo->mediareqok ? "available" : "unavailable");
|
||||
fprintf(fp, " probes: %d, dadcount = %d\n",
|
||||
ifinfo->probes, ifinfo->dadcount);
|
||||
if (ifinfo->timer.tv_sec == tm_max.tv_sec &&
|
||||
ifinfo->timer.tv_usec == tm_max.tv_usec)
|
||||
fprintf(fp, " no timer\n");
|
||||
else {
|
||||
fprintf(fp, " timer: interval=%d:%d, expire=%s\n",
|
||||
(int)ifinfo->timer.tv_sec,
|
||||
(int)ifinfo->timer.tv_usec,
|
||||
(ifinfo->expire.tv_sec < now.tv_sec) ? "expired"
|
||||
: sec2str(ifinfo->expire.tv_sec - now.tv_sec));
|
||||
}
|
||||
fprintf(fp, " number of valid RAs: %d\n", ifinfo->racnt);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rtsold_dump_file(dumpfile)
|
||||
char *dumpfile;
|
||||
{
|
||||
if ((fp = fopen(dumpfile, "w")) == NULL) {
|
||||
warnmsg(LOG_WARNING, __FUNCTION__, "open a dump file(%s)",
|
||||
dumpfile, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
dump_interface_status();
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static char *
|
||||
sec2str(total)
|
||||
time_t total;
|
||||
{
|
||||
static char result[256];
|
||||
int days, hours, mins, secs;
|
||||
int first = 1;
|
||||
char *p = result;
|
||||
|
||||
days = total / 3600 / 24;
|
||||
hours = (total / 3600) % 24;
|
||||
mins = (total / 60) % 60;
|
||||
secs = total % 60;
|
||||
|
||||
if (days) {
|
||||
first = 0;
|
||||
p += sprintf(p, "%dd", days);
|
||||
}
|
||||
if (!first || hours) {
|
||||
first = 0;
|
||||
p += sprintf(p, "%dh", hours);
|
||||
}
|
||||
if (!first || mins) {
|
||||
first = 0;
|
||||
p += sprintf(p, "%dm", mins);
|
||||
}
|
||||
sprintf(p, "%ds", secs);
|
||||
|
||||
return(result);
|
||||
}
|
423
usr.sbin/rtsold/if.c
Normal file
423
usr.sbin/rtsold/if.c
Normal file
@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
#include <net/if_var.h>
|
||||
#endif /* __FreeBSD__ >= 3 */
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#ifdef __FreeBSD__
|
||||
# include <net/ethernet.h>
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
#include <net/if_ether.h>
|
||||
#endif
|
||||
#if defined(__bsdi__) || defined(__OpenBSD__)
|
||||
# include <netinet/in.h>
|
||||
# include <netinet/if_ether.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include <netinet6/in6_var.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <kvm.h>
|
||||
#include <nlist.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "rtsold.h"
|
||||
|
||||
static int ifsock;
|
||||
|
||||
static int getifa __P((char *name, struct in6_ifaddr *ifap));
|
||||
static void get_rtaddrs __P((int addrs, struct sockaddr *sa,
|
||||
struct sockaddr **rti_info));
|
||||
|
||||
int
|
||||
ifinit()
|
||||
{
|
||||
if ((ifsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
interface_up(char *name)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct in6_ifaddr ifa;
|
||||
|
||||
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||
|
||||
if (ioctl(ifsock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
|
||||
warnmsg(LOG_WARNING, __FUNCTION__, "ioctl(SIOCGIFFLAGS): %s",
|
||||
strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
if (!(ifr.ifr_flags & IFF_UP)) {
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
if (ioctl(ifsock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"ioctl(SIOCSIFFLAGS): %s", strerror(errno));
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__, "checking if %s is ready...", name);
|
||||
|
||||
if (getifa(name, &ifa) < 0) {
|
||||
warnmsg(LOG_WARNING, __FUNCTION__,
|
||||
"getifa() failed, anyway I'll try");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(ifa.ia6_flags & IN6_IFF_NOTREADY)) {
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__,
|
||||
"%s is ready", name);
|
||||
return(0);
|
||||
}
|
||||
else {
|
||||
if (ifa.ia6_flags & IN6_IFF_TENTATIVE) {
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__, "%s is tentative",
|
||||
name);
|
||||
return IFS_TENTATIVE;
|
||||
}
|
||||
if (ifa.ia6_flags & IN6_IFF_DUPLICATED)
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__, "%s is duplicated",
|
||||
name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
interface_status(struct ifinfo *ifinfo)
|
||||
{
|
||||
char *ifname = ifinfo->ifname;
|
||||
struct ifreq ifr;
|
||||
struct ifmediareq ifmr;
|
||||
|
||||
/* get interface flags */
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
if (ioctl(ifsock, SIOCGIFFLAGS, &ifr) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "ioctl(SIOCGIFFLAGS) on %s: %s",
|
||||
ifname, strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
/*
|
||||
* if one of UP and RUNNING flags is dropped,
|
||||
* the interface is not active.
|
||||
*/
|
||||
if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
|
||||
goto inactive;
|
||||
}
|
||||
|
||||
/* Next, check carrier on the interface, if possible */
|
||||
if (!ifinfo->mediareqok)
|
||||
goto active;
|
||||
memset(&ifmr, 0, sizeof(ifmr));
|
||||
strncpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
|
||||
|
||||
if (ioctl(ifsock, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
|
||||
if (errno != EINVAL) {
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__,
|
||||
"ioctl(SIOCGIFMEDIA) on %s: %s",
|
||||
ifname, strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
/*
|
||||
* EINVAL simply means that the interface does not support
|
||||
* the SIOCGIFMEDIA ioctl. We regard it alive.
|
||||
*/
|
||||
ifinfo->mediareqok = 0;
|
||||
goto active;
|
||||
}
|
||||
|
||||
if (ifmr.ifm_status & IFM_AVALID) {
|
||||
switch(ifmr.ifm_active & IFM_NMASK) {
|
||||
case IFM_ETHER:
|
||||
if (ifmr.ifm_status & IFM_ACTIVE)
|
||||
goto active;
|
||||
else
|
||||
goto inactive;
|
||||
break;
|
||||
default:
|
||||
goto inactive;
|
||||
}
|
||||
}
|
||||
|
||||
inactive:
|
||||
return(0);
|
||||
|
||||
active:
|
||||
return(1);
|
||||
}
|
||||
|
||||
#define ROUNDUP(a, size) \
|
||||
(((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
|
||||
|
||||
#define NEXT_SA(ap) (ap) = (struct sockaddr *) \
|
||||
((caddr_t)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\
|
||||
sizeof(u_long)) :\
|
||||
sizeof(u_long)))
|
||||
#define ROUNDUP8(a) (1 + (((a) - 1) | 7))
|
||||
|
||||
int
|
||||
lladdropt_length(struct sockaddr_dl *sdl)
|
||||
{
|
||||
switch(sdl->sdl_type) {
|
||||
case IFT_ETHER:
|
||||
return(ROUNDUP8(ETHER_ADDR_LEN + 2));
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt)
|
||||
{
|
||||
char *addr;
|
||||
|
||||
ndopt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; /* fixed */
|
||||
|
||||
switch(sdl->sdl_type) {
|
||||
case IFT_ETHER:
|
||||
ndopt->nd_opt_len = (ROUNDUP8(ETHER_ADDR_LEN + 2)) >> 3;
|
||||
addr = (char *)(ndopt + 1);
|
||||
memcpy(addr, LLADDR(sdl), ETHER_ADDR_LEN);
|
||||
break;
|
||||
default:
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"unsupported link type(%d)", sdl->sdl_type);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_dl *
|
||||
if_nametosdl(char *name)
|
||||
{
|
||||
int mib[6] = {CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
|
||||
char *buf, *next, *lim;
|
||||
size_t len;
|
||||
struct if_msghdr *ifm;
|
||||
struct sockaddr *sa, *rti_info[RTAX_MAX];
|
||||
struct sockaddr_dl *sdl = NULL, *ret_sdl;
|
||||
|
||||
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
|
||||
return(NULL);
|
||||
if ((buf = malloc(len)) == NULL)
|
||||
return(NULL);
|
||||
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
|
||||
free(buf);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
lim = buf + len;
|
||||
for (next = buf; next < lim; next += ifm->ifm_msglen) {
|
||||
ifm = (struct if_msghdr *)next;
|
||||
if (ifm->ifm_type == RTM_IFINFO) {
|
||||
sa = (struct sockaddr *)(ifm + 1);
|
||||
get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
|
||||
if ((sa = rti_info[RTAX_IFP]) != NULL) {
|
||||
if (sa->sa_family == AF_LINK) {
|
||||
sdl = (struct sockaddr_dl *)sa;
|
||||
if (strncmp(&sdl->sdl_data[0],
|
||||
name,
|
||||
sdl->sdl_nlen) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (next == lim) {
|
||||
/* search failed */
|
||||
free(buf);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if ((ret_sdl = malloc(sdl->sdl_len)) == NULL)
|
||||
return(NULL);
|
||||
memcpy((caddr_t)ret_sdl, (caddr_t)sdl, sdl->sdl_len);
|
||||
|
||||
return(ret_sdl);
|
||||
}
|
||||
|
||||
int
|
||||
getinet6sysctl(int code)
|
||||
{
|
||||
int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, 0 };
|
||||
int value;
|
||||
size_t size;
|
||||
|
||||
mib[3] = code;
|
||||
size = sizeof(value);
|
||||
if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size, NULL, 0) < 0)
|
||||
return -1;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
|
||||
static struct nlist nl[] = {
|
||||
#define N_IFNET 0
|
||||
{ "_ifnet" },
|
||||
{ "" },
|
||||
};
|
||||
|
||||
#define KREAD(x, y, z) { \
|
||||
if (kvm_read(kvmd, (u_long)x, (void *)y, sizeof(z)) != sizeof(z)) { \
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "kvm_read failed"); \
|
||||
goto bad; \
|
||||
} \
|
||||
}
|
||||
|
||||
static int
|
||||
getifa(char *name, struct in6_ifaddr *ifap)
|
||||
{
|
||||
u_short index;
|
||||
kvm_t *kvmd = NULL;
|
||||
char buf[_POSIX2_LINE_MAX];
|
||||
struct ifnet *ifp;
|
||||
struct ifnet ifnet;
|
||||
struct in6_ifaddr *ifa;
|
||||
|
||||
if (!ifap)
|
||||
exit(1);
|
||||
|
||||
index = (u_short)if_nametoindex(name);
|
||||
if (index == 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "if_nametoindex failed for %s",
|
||||
name);
|
||||
goto bad;
|
||||
}
|
||||
if ((kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf)) == NULL) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "kvm_openfiles failed");
|
||||
goto bad;
|
||||
}
|
||||
if (kvm_nlist(kvmd, nl) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "kvm_nlist failed");
|
||||
goto bad;
|
||||
}
|
||||
if (nl[N_IFNET].n_value == 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "symbol \"%s\" not found",
|
||||
nl[N_IFNET].n_name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *);
|
||||
while (ifp) {
|
||||
KREAD(ifp, &ifnet, struct ifnet);
|
||||
if (ifnet.if_index == index)
|
||||
break;
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
ifp = TAILQ_NEXT(&ifnet, if_list);
|
||||
#elif defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
ifp = TAILQ_NEXT(&ifnet, if_link);
|
||||
#else
|
||||
ifp = ifnet.if_next;
|
||||
#endif
|
||||
}
|
||||
if (!ifp) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "interface \"%s\" not found",
|
||||
name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
ifa = (struct in6_ifaddr *)TAILQ_FIRST(&ifnet.if_addrlist);
|
||||
#elif defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
ifa = (struct in6_ifaddr *)TAILQ_FIRST(&ifnet.if_addrhead);
|
||||
#else
|
||||
ifa = (struct in6_ifaddr *)ifnet.if_addrlist;
|
||||
#endif
|
||||
while (ifa) {
|
||||
KREAD(ifa, ifap, *ifap);
|
||||
if (ifap->ia_addr.sin6_family == AF_INET6
|
||||
&& IN6_IS_ADDR_LINKLOCAL(&ifap->ia_addr.sin6_addr)) {
|
||||
kvm_close(kvmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
ifa = (struct in6_ifaddr *)
|
||||
TAILQ_NEXT((struct ifaddr *)ifap, ifa_list);
|
||||
#elif defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
ifa = (struct in6_ifaddr *)
|
||||
TAILQ_NEXT((struct ifaddr *)ifap, ifa_link);
|
||||
#else
|
||||
ifa = (struct in6_ifaddr *)(((struct ifaddr *)ifap)->ifa_next);
|
||||
#endif
|
||||
}
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "no IPv6 link-local address for %s",
|
||||
name);
|
||||
|
||||
bad:
|
||||
if (kvmd)
|
||||
kvm_close(kvmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
NEXT_SA(sa);
|
||||
}
|
||||
else
|
||||
rti_info[i] = NULL;
|
||||
}
|
||||
}
|
179
usr.sbin/rtsold/probe.c
Normal file
179
usr.sbin/rtsold/probe.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
#include <net/if_var.h>
|
||||
#endif /* __FreeBSD__ >= 3 */
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "rtsold.h"
|
||||
|
||||
static struct msghdr sndmhdr;
|
||||
static struct iovec sndiov[2];
|
||||
static int probesock;
|
||||
static void sendprobe __P((struct in6_addr *addr, int ifindex));
|
||||
|
||||
int
|
||||
probe_init()
|
||||
{
|
||||
static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
|
||||
CMSG_SPACE(sizeof(int))];
|
||||
|
||||
if ((probesock = socket(AF_INET6, SOCK_RAW, IPPROTO_NONE)) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* make the socket send-only */
|
||||
if (shutdown(probesock, 0)) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "shutdown: %s", strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* initialize msghdr for sending packets */
|
||||
sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
|
||||
sndmhdr.msg_iov = sndiov;
|
||||
sndmhdr.msg_iovlen = 1;
|
||||
sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
|
||||
sndmhdr.msg_controllen = sizeof(sndcmsgbuf);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe if each router in the default router list is still alive.
|
||||
*/
|
||||
void
|
||||
defrouter_probe(int ifindex)
|
||||
{
|
||||
struct in6_drlist dr;
|
||||
int s, i;
|
||||
u_char ntopbuf[INET6_ADDRSTRLEN];
|
||||
|
||||
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
bzero(&dr, sizeof(dr));
|
||||
strcpy(dr.ifname, "lo0"); /* dummy interface */
|
||||
if (ioctl(s, SIOCGDRLST_IN6, (caddr_t)&dr) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "ioctl(SIOCGDRLST_IN6): %s",
|
||||
strerror(errno));
|
||||
goto closeandend;
|
||||
}
|
||||
|
||||
for(i = 0; dr.defrouter[i].if_index && i < PRLSTSIZ; i++) {
|
||||
if (ifindex && dr.defrouter[i].if_index == ifindex) {
|
||||
/* sanity check */
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(&dr.defrouter[i].rtaddr)) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"default router list contains a "
|
||||
"non-linklocal address(%s)",
|
||||
inet_ntop(AF_INET6,
|
||||
&dr.defrouter[i].rtaddr,
|
||||
ntopbuf, INET6_ADDRSTRLEN));
|
||||
continue; /* ignore the address */
|
||||
}
|
||||
sendprobe(&dr.defrouter[i].rtaddr,
|
||||
dr.defrouter[i].if_index);
|
||||
}
|
||||
}
|
||||
|
||||
closeandend:
|
||||
close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
sendprobe(struct in6_addr *addr, int ifindex)
|
||||
{
|
||||
struct sockaddr_in6 sa6_probe;
|
||||
struct in6_pktinfo *pi;
|
||||
struct cmsghdr *cm;
|
||||
u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];;
|
||||
|
||||
bzero(&sa6_probe, sizeof(sa6_probe));
|
||||
sa6_probe.sin6_family = AF_INET6;
|
||||
sa6_probe.sin6_len = sizeof(sa6_probe);
|
||||
sa6_probe.sin6_addr = *addr;
|
||||
|
||||
sndmhdr.msg_name = (caddr_t)&sa6_probe;
|
||||
sndmhdr.msg_iov[0].iov_base = NULL;
|
||||
sndmhdr.msg_iov[0].iov_len = 0;
|
||||
|
||||
cm = CMSG_FIRSTHDR(&sndmhdr);
|
||||
/* specify the outgoing interface */
|
||||
cm->cmsg_level = IPPROTO_IPV6;
|
||||
cm->cmsg_type = IPV6_PKTINFO;
|
||||
cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
pi = (struct in6_pktinfo *)CMSG_DATA(cm);
|
||||
memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/
|
||||
pi->ipi6_ifindex = ifindex;
|
||||
|
||||
/* specify the hop limit of the packet for safety */
|
||||
{
|
||||
int hoplimit = 1;
|
||||
|
||||
cm = CMSG_NXTHDR(&sndmhdr, cm);
|
||||
cm->cmsg_level = IPPROTO_IPV6;
|
||||
cm->cmsg_type = IPV6_HOPLIMIT;
|
||||
cm->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int));
|
||||
}
|
||||
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__, "probe a router %s on %s",
|
||||
inet_ntop(AF_INET6, addr, ntopbuf, INET6_ADDRSTRLEN),
|
||||
if_indextoname(ifindex, ifnamebuf));
|
||||
|
||||
if (sendmsg(probesock, &sndmhdr, 0))
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "sendmsg on %s: %s",
|
||||
if_indextoname(ifindex, ifnamebuf), strerror(errno));
|
||||
|
||||
return;
|
||||
}
|
312
usr.sbin/rtsold/rtsol.c
Normal file
312
usr.sbin/rtsold/rtsol.c
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet6/ip6_var.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include "rtsold.h"
|
||||
|
||||
#define ALLROUTER "ff02::2"
|
||||
|
||||
static struct msghdr rcvmhdr;
|
||||
static struct msghdr sndmhdr;
|
||||
static struct iovec rcviov[2];
|
||||
static struct iovec sndiov[2];
|
||||
static struct sockaddr_in6 from;
|
||||
|
||||
static int rssock;
|
||||
|
||||
static struct sockaddr_in6 sin6_allrouters = {sizeof(sin6_allrouters), AF_INET6};
|
||||
|
||||
int
|
||||
sockopen()
|
||||
{
|
||||
int on;
|
||||
struct icmp6_filter filt;
|
||||
static u_char answer[1500];
|
||||
static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
|
||||
CMSG_SPACE(sizeof(int))];
|
||||
static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
|
||||
CMSG_SPACE(sizeof(int))];
|
||||
|
||||
memset(&sin6_allrouters, 0, sizeof(struct sockaddr_in6));
|
||||
if (inet_pton(AF_INET6, ALLROUTER,
|
||||
&sin6_allrouters.sin6_addr.s6_addr) != 1) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "inet_pton failed for %s",
|
||||
ALLROUTER);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if ((rssock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* specify to tell receiving interface */
|
||||
on = 1;
|
||||
if (setsockopt(rssock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
|
||||
sizeof(on)) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "IPV6_PKTINFO: %s",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
on = 1;
|
||||
/* specify to tell value of hoplimit field of received IP6 hdr */
|
||||
if (setsockopt(rssock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
|
||||
sizeof(on)) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "IPV6_HOPLIMIT: %s",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* specfiy to accept only router advertisements on the socket */
|
||||
ICMP6_FILTER_SETBLOCKALL(&filt);
|
||||
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
|
||||
if (setsockopt(rssock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
|
||||
sizeof(filt)) == -1) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "setsockopt(ICMP6_FILTER): %s",
|
||||
strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* initialize msghdr for receiving packets */
|
||||
rcviov[0].iov_base = (caddr_t)answer;
|
||||
rcviov[0].iov_len = sizeof(answer);
|
||||
rcvmhdr.msg_name = (caddr_t)&from;
|
||||
rcvmhdr.msg_namelen = sizeof(from);
|
||||
rcvmhdr.msg_iov = rcviov;
|
||||
rcvmhdr.msg_iovlen = 1;
|
||||
rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
|
||||
rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf);
|
||||
|
||||
/* initialize msghdr for sending packets */
|
||||
sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
|
||||
sndmhdr.msg_iov = sndiov;
|
||||
sndmhdr.msg_iovlen = 1;
|
||||
sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
|
||||
sndmhdr.msg_controllen = sizeof(sndcmsgbuf);
|
||||
|
||||
return(rssock);
|
||||
}
|
||||
|
||||
void
|
||||
sendpacket(struct ifinfo *ifinfo)
|
||||
{
|
||||
int i;
|
||||
struct cmsghdr *cm;
|
||||
struct in6_pktinfo *pi;
|
||||
|
||||
sndmhdr.msg_name = (caddr_t)&sin6_allrouters;
|
||||
sndmhdr.msg_iov[0].iov_base = (caddr_t)ifinfo->rs_data;
|
||||
sndmhdr.msg_iov[0].iov_len = ifinfo->rs_datalen;
|
||||
|
||||
cm = CMSG_FIRSTHDR(&sndmhdr);
|
||||
/* specify the outgoing interface */
|
||||
cm->cmsg_level = IPPROTO_IPV6;
|
||||
cm->cmsg_type = IPV6_PKTINFO;
|
||||
cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
pi = (struct in6_pktinfo *)CMSG_DATA(cm);
|
||||
memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/
|
||||
pi->ipi6_ifindex = ifinfo->sdl->sdl_index;
|
||||
|
||||
/* specify the hop limit of the packet */
|
||||
{
|
||||
int hoplimit = 255;
|
||||
|
||||
cm = CMSG_NXTHDR(&sndmhdr, cm);
|
||||
cm->cmsg_level = IPPROTO_IPV6;
|
||||
cm->cmsg_type = IPV6_HOPLIMIT;
|
||||
cm->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int));
|
||||
}
|
||||
|
||||
warnmsg(LOG_DEBUG,
|
||||
__FUNCTION__, "send RS on %s, whose state is %d",
|
||||
ifinfo->ifname, ifinfo->state);
|
||||
|
||||
i = sendmsg(rssock, &sndmhdr, 0);
|
||||
|
||||
if (i < 0 || i != ifinfo->rs_datalen) {
|
||||
/*
|
||||
* ENETDOWN is not so serious, especially when using several
|
||||
* network cards on a mobile node. We ignore it.
|
||||
*/
|
||||
if (errno != ENETDOWN || dflag > 0)
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "sendmsg on %s: %s",
|
||||
ifinfo->ifname, strerror(errno));
|
||||
}
|
||||
|
||||
/* update counter */
|
||||
ifinfo->probes++;
|
||||
}
|
||||
|
||||
void
|
||||
rtsol_input(int s)
|
||||
{
|
||||
int i;
|
||||
int *hlimp = NULL;
|
||||
struct icmp6_hdr *icp;
|
||||
int ifindex = 0;
|
||||
struct cmsghdr *cm;
|
||||
struct in6_pktinfo *pi = NULL;
|
||||
struct ifinfo *ifi = NULL;
|
||||
u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
|
||||
|
||||
/* get message */
|
||||
if ((i = recvmsg(s, &rcvmhdr, 0)) < 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "recvmsg: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* extract optional information via Advanced API */
|
||||
for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rcvmhdr);
|
||||
cm;
|
||||
cm = (struct cmsghdr *)CMSG_NXTHDR(&rcvmhdr, cm)) {
|
||||
if (cm->cmsg_level == IPPROTO_IPV6 &&
|
||||
cm->cmsg_type == IPV6_PKTINFO &&
|
||||
cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {
|
||||
pi = (struct in6_pktinfo *)(CMSG_DATA(cm));
|
||||
ifindex = pi->ipi6_ifindex;
|
||||
}
|
||||
if (cm->cmsg_level == IPPROTO_IPV6 &&
|
||||
cm->cmsg_type == IPV6_HOPLIMIT &&
|
||||
cm->cmsg_len == CMSG_LEN(sizeof(int)))
|
||||
hlimp = (int *)CMSG_DATA(cm);
|
||||
}
|
||||
|
||||
if (ifindex == 0) {
|
||||
warnmsg(LOG_ERR,
|
||||
__FUNCTION__, "failed to get receiving interface");
|
||||
return;
|
||||
}
|
||||
if (hlimp == NULL) {
|
||||
warnmsg(LOG_ERR,
|
||||
__FUNCTION__, "failed to get receiving hop limit");
|
||||
return;
|
||||
}
|
||||
|
||||
if (i < sizeof(struct nd_router_advert)) {
|
||||
warnmsg(LOG_ERR,
|
||||
__FUNCTION__, "packet size(%d) is too short", i);
|
||||
return;
|
||||
}
|
||||
|
||||
icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base;
|
||||
|
||||
if (icp->icmp6_type != ND_ROUTER_ADVERT) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"invalid icmp type(%d) from %s on %s", icp->icmp6_type,
|
||||
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
|
||||
INET6_ADDRSTRLEN),
|
||||
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
|
||||
return;
|
||||
}
|
||||
|
||||
if (icp->icmp6_code != 0) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"invalid icmp code(%d) from %s on %s", icp->icmp6_code,
|
||||
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
|
||||
INET6_ADDRSTRLEN),
|
||||
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*hlimp != 255) {
|
||||
warnmsg(LOG_NOTICE, __FUNCTION__,
|
||||
"invalid RA with hop limit(%d) from %s on %s",
|
||||
*hlimp,
|
||||
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
|
||||
INET6_ADDRSTRLEN),
|
||||
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pi && !IN6_IS_ADDR_LINKLOCAL(&from.sin6_addr)) {
|
||||
warnmsg(LOG_NOTICE, __FUNCTION__,
|
||||
"invalid RA with non link-local source from %s on %s",
|
||||
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
|
||||
INET6_ADDRSTRLEN),
|
||||
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
|
||||
return;
|
||||
}
|
||||
|
||||
/* xxx: more validation? */
|
||||
|
||||
if ((ifi = find_ifinfo(pi->ipi6_ifindex)) == NULL) {
|
||||
warnmsg(LOG_NOTICE, __FUNCTION__,
|
||||
"received RA from %s on an unexpeced IF(%s)",
|
||||
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
|
||||
INET6_ADDRSTRLEN),
|
||||
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
|
||||
return;
|
||||
}
|
||||
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__,
|
||||
"received RA from %s on %s, state is %d",
|
||||
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
|
||||
INET6_ADDRSTRLEN),
|
||||
ifi->ifname, ifi->state);
|
||||
|
||||
ifi->racnt++;
|
||||
|
||||
switch(ifi->state) {
|
||||
case IFS_IDLE: /* should be ignored */
|
||||
case IFS_DELAY: /* right? */
|
||||
break;
|
||||
case IFS_PROBE:
|
||||
ifi->state = IFS_IDLE;
|
||||
ifi->probes = 0;
|
||||
rtsol_timer_update(ifi);
|
||||
break;
|
||||
}
|
||||
}
|
175
usr.sbin/rtsold/rtsold.8
Normal file
175
usr.sbin/rtsold/rtsold.8
Normal file
@ -0,0 +1,175 @@
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" 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 project 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 PROJECT 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 PROJECT 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.
|
||||
.\"
|
||||
.\" $Id: rtsold.8,v 1.4 1999/09/30 00:57:15 jinmei Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 17, 1998
|
||||
.Dt RTSOLD 8
|
||||
.Os KAME
|
||||
.\"
|
||||
.Sh NAME
|
||||
.Nm rtsold
|
||||
.Nd router solicitation daemon
|
||||
.\"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl dDfm1
|
||||
.Ar interface ...
|
||||
.Nm rtsol
|
||||
.Op Fl dD
|
||||
.Ar interface ...
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Nm Rtsold
|
||||
is the daemon program to send ICMPv6 Router Solicitation messages
|
||||
on the specified interfaces.
|
||||
If a node (re)attaches to a link,
|
||||
.Nm
|
||||
sends some Router Solicitations on the link destined to the link-local scope
|
||||
all-routers multicast address to discover new routers
|
||||
and to get non link-local addresses.
|
||||
.Lp
|
||||
Specifically,
|
||||
.Nm
|
||||
sends at most 3 Router Solicitations on an interface
|
||||
after one of the following events:
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
Just after invocation of
|
||||
.Nm
|
||||
daemon.
|
||||
.It
|
||||
The interface is up after a temporary interface failure.
|
||||
.Nm Rtsold
|
||||
detects it by periodically probing if the status of the
|
||||
interface is active or not.
|
||||
Note that some network cards and drivers do not allow users
|
||||
to extract link state.
|
||||
In such cases,
|
||||
.Nm
|
||||
cannot detect the change of the interface status.
|
||||
.It
|
||||
Every one minute if
|
||||
.Fl m
|
||||
option is specified and
|
||||
.Nm
|
||||
daemon cannot get the interface status.
|
||||
This feature does not conform to IPv6 neighbor discovery
|
||||
specification, but is provided for mobile stations.
|
||||
Default interval of router advertisements, which is on the order of 10
|
||||
minutes, is slightly long for mobile stations.
|
||||
This feature is provided
|
||||
for such stations so that they can find new routers as soon as possible
|
||||
when they attach another link.
|
||||
.El
|
||||
.Lp
|
||||
Once
|
||||
.Nm
|
||||
sends a Router Solicitation, and receives a valid Router Advertisement,
|
||||
it desists from sending additional solicitations on that interface, until
|
||||
the next time one of the above events occurs.
|
||||
.Lp
|
||||
When sending a Router Solicitation on an interface,
|
||||
.Nm
|
||||
includes a Source Link-layer address option if the interface
|
||||
has its link-layer address.
|
||||
.Pp
|
||||
Upon receipt of signal
|
||||
.Dv SIGUSR1 ,
|
||||
.Nm
|
||||
will dump the current internal state into
|
||||
.Pa /var/tmp/rtsold.dump.
|
||||
.\"
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width indent
|
||||
.\"
|
||||
.It Fl d
|
||||
Enable debugging.
|
||||
.It Fl D
|
||||
Enable more debugging including to print internal timer information.
|
||||
.It Fl f
|
||||
.Fl f
|
||||
prevents
|
||||
.Nm
|
||||
from becoming a daemon (foreground mode).
|
||||
Warning messages are generated to standard error output,
|
||||
instead of
|
||||
.Xr syslog 3 .
|
||||
.It Fl m
|
||||
Enable mobility support.
|
||||
If this option is specified,
|
||||
.Nm
|
||||
sends probing packets to default routers that have advertised Router
|
||||
Advertisements
|
||||
when the node (re)attaches to an interface.
|
||||
Moreover, if the option is specified,
|
||||
.Nm
|
||||
periodically sends Router Solicitation on an interface that does not support
|
||||
.Dv SIOCGIFMEDIA
|
||||
ioctl.
|
||||
.It Fl 1
|
||||
Perform only one probe.
|
||||
Transmit Router Solcitation packet until valid Router Advertisement packet
|
||||
arrives all the interfaces more than once, then exit.
|
||||
.El
|
||||
.Pp
|
||||
If you invoke the program as
|
||||
.Nm rtsol ,
|
||||
it will behave as
|
||||
.Do
|
||||
.Nm
|
||||
.Fl f1
|
||||
.Ar interfaces
|
||||
.Dc .
|
||||
.Sh RETURN VALUES
|
||||
The program exits with 0 on success, non-zero on failures.
|
||||
.\"
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/run/rtsold.dump -compact
|
||||
.It Pa /var/run/rtsold.pid
|
||||
the pid of the currently running
|
||||
.Nm rtsold .
|
||||
.It Pa /var/tmp/rtsold.dump
|
||||
dumps internal state on.
|
||||
.El
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr rtadvd 8 ,
|
||||
.Xr sysctl 8
|
||||
.\"
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command is based on
|
||||
.Nm rtsol
|
||||
command, which first appeared in WIDE/KAME IPv6 protocol stack kit.
|
||||
.Nm rtsol
|
||||
is now integrated into
|
||||
.Xr rtsold 8 .
|
||||
.\" .Sh BUGS
|
||||
.\" (to be written)
|
622
usr.sbin/rtsold/rtsold.c
Normal file
622
usr.sbin/rtsold/rtsold.c
Normal file
@ -0,0 +1,622 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <stdarg.h>
|
||||
#include "rtsold.h"
|
||||
|
||||
struct ifinfo *iflist;
|
||||
struct timeval tm_max = {0x7fffffff, 0x7fffffff};
|
||||
int dflag;
|
||||
static int log_upto = 999;
|
||||
static int fflag = 0;
|
||||
|
||||
/* protocol constatns */
|
||||
#define MAX_RTR_SOLICITATION_DELAY 1 /* second */
|
||||
#define RTR_SOLICITATION_INTERVAL 4 /* seconds */
|
||||
#define MAX_RTR_SOLICITATIONS 3 /* times */
|
||||
|
||||
/* implementation dependent constants */
|
||||
#define PROBE_INTERVAL 60 /* secondes XXX: should be configurable */
|
||||
|
||||
/* utility macros */
|
||||
/* a < b */
|
||||
#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\
|
||||
(((a).tv_sec == (b).tv_sec) && \
|
||||
((a).tv_usec < (b).tv_usec)))
|
||||
|
||||
/* a <= b */
|
||||
#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\
|
||||
(((a).tv_sec == (b).tv_sec) &&\
|
||||
((a).tv_usec <= (b).tv_usec)))
|
||||
|
||||
/* a == b */
|
||||
#define TIMEVAL_EQ(a, b) (((a).tv_sec==(b).tv_sec) && ((a).tv_usec==(b).tv_usec))
|
||||
|
||||
int main __P((int argc, char *argv[]));
|
||||
|
||||
/* static variables and functions */
|
||||
static int mobile_node = 0;
|
||||
static int do_dump;
|
||||
static char *dumpfilename = "/var/tmp/rtsold.dump"; /* XXX: should be configurable */
|
||||
static char *pidfilename = "/var/run/rtsold.pid"; /* should be configurable */
|
||||
|
||||
static int ifconfig __P((char *ifname));
|
||||
static int make_packet __P((struct ifinfo *ifinfo));
|
||||
static struct timeval *rtsol_check_timer __P((void));
|
||||
static void TIMEVAL_ADD __P((struct timeval *a, struct timeval *b,
|
||||
struct timeval *result));
|
||||
static void TIMEVAL_SUB __P((struct timeval *a, struct timeval *b,
|
||||
struct timeval *result));
|
||||
|
||||
static void rtsold_set_dump_file __P(());
|
||||
static void usage __P((char *progname));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int s, ch;
|
||||
int once = 0;
|
||||
struct timeval *timeout;
|
||||
struct fd_set fdset;
|
||||
char *argv0;
|
||||
char *opts;
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
argv0 = argv[0];
|
||||
|
||||
/* get option */
|
||||
if (argv0 && argv0[strlen(argv0) - 1] != 'd') {
|
||||
fflag = 1;
|
||||
once = 1;
|
||||
opts = "dD";
|
||||
} else
|
||||
opts = "dDfm1";
|
||||
|
||||
while ((ch = getopt(argc, argv, opts)) != -1) {
|
||||
switch(ch) {
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
break;
|
||||
case 'D':
|
||||
dflag = 2;
|
||||
break;
|
||||
case 'f':
|
||||
fflag = 1;
|
||||
break;
|
||||
case 'm':
|
||||
mobile_node = 1;
|
||||
break;
|
||||
case '1':
|
||||
once = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv0);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc == 0)
|
||||
usage(argv0);
|
||||
|
||||
/* set log level */
|
||||
if (dflag == 0)
|
||||
log_upto = LOG_NOTICE;
|
||||
if (!fflag) {
|
||||
char *ident;
|
||||
ident = strrchr(argv0, '/');
|
||||
if (!ident)
|
||||
ident = argv0;
|
||||
else
|
||||
ident++;
|
||||
openlog(ident, LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||
if (log_upto >= 0)
|
||||
setlogmask(LOG_UPTO(log_upto));
|
||||
}
|
||||
|
||||
/* random value initilization */
|
||||
srandom((u_long)time(NULL));
|
||||
|
||||
/* warn if accept_rtadv is down */
|
||||
if (!getinet6sysctl(IPV6CTL_ACCEPT_RTADV))
|
||||
warnx("kernel is configured not to accept RAs");
|
||||
|
||||
/* initialization to dump internal status to a file */
|
||||
if (signal(SIGUSR1, (void *)rtsold_set_dump_file) < 0)
|
||||
errx(1, "failed to set signal for dump status");
|
||||
|
||||
/* configuration per interface */
|
||||
if (ifinit())
|
||||
errx(1, "failed to initilizatoin interfaces");
|
||||
while (argc--) {
|
||||
if (ifconfig(*argv))
|
||||
errx(1, "failed to initilize %s", *argv);
|
||||
argv++;
|
||||
}
|
||||
|
||||
/* open a socket for sending RS and receiving RA */
|
||||
if ((s = sockopen()) < 0)
|
||||
errx(1, "failed to open a socket");
|
||||
|
||||
/* setup for probing default routers */
|
||||
if (probe_init())
|
||||
errx(1, "failed to setup for probing routers");
|
||||
|
||||
if (!fflag)
|
||||
daemon(0, 0); /* act as a daemon */
|
||||
|
||||
/* dump the current pid */
|
||||
if (!once) {
|
||||
pid_t pid = getpid();
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = fopen(pidfilename, "w")) == NULL)
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"failed to open a log file(%s)",
|
||||
pidfilename, strerror(errno));
|
||||
else {
|
||||
fprintf(fp, "%d\n", pid);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(s, &fdset);
|
||||
while (1) { /* main loop */
|
||||
extern int errno;
|
||||
int e;
|
||||
struct fd_set select_fd = fdset;
|
||||
|
||||
if (do_dump) { /* SIGUSR1 */
|
||||
do_dump = 0;
|
||||
rtsold_dump_file(dumpfilename);
|
||||
}
|
||||
|
||||
timeout = rtsol_check_timer();
|
||||
|
||||
if (once) {
|
||||
struct ifinfo *ifi;
|
||||
|
||||
/* if we have no timeout, we are done (or failed) */
|
||||
if (timeout == NULL)
|
||||
break;
|
||||
|
||||
/* if all interfaces have got RA packet, we are done */
|
||||
for (ifi = iflist; ifi; ifi = ifi->next) {
|
||||
if (ifi->state != IFS_DOWN && ifi->racnt == 0)
|
||||
break;
|
||||
}
|
||||
if (ifi == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((e = select(s + 1, &select_fd, NULL, NULL, timeout)) < 1) {
|
||||
if (e < 0 && errno != EINTR) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "select: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* packet reception */
|
||||
if (FD_ISSET(s, &fdset))
|
||||
rtsol_input(s);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ifconfig(char *ifname)
|
||||
{
|
||||
struct ifinfo *ifinfo;
|
||||
struct sockaddr_dl *sdl;
|
||||
int flags;
|
||||
|
||||
if ((sdl = if_nametosdl(ifname)) == NULL) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"failed to get link layer information for %s", ifname);
|
||||
return(-1);
|
||||
}
|
||||
if (find_ifinfo(sdl->sdl_index)) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"interface %s was already cofigured", ifname);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__, "memory allocation failed");
|
||||
return(-1);
|
||||
}
|
||||
memset(ifinfo, 0, sizeof(*ifinfo));
|
||||
ifinfo->sdl = sdl;
|
||||
|
||||
strncpy(ifinfo->ifname, ifname, sizeof(ifinfo->ifname));
|
||||
|
||||
/* construct a router solicitation message */
|
||||
if (make_packet(ifinfo))
|
||||
goto bad;
|
||||
|
||||
/*
|
||||
* check if the interface is available.
|
||||
* also check if SIOCGIFMEDIA ioctl is OK on the interface.
|
||||
*/
|
||||
ifinfo->mediareqok = 1;
|
||||
ifinfo->active = interface_status(ifinfo);
|
||||
if (!ifinfo->mediareqok) {
|
||||
/*
|
||||
* probe routers periodically even if the link status
|
||||
* does not change.
|
||||
*/
|
||||
ifinfo->probeinterval = PROBE_INTERVAL;
|
||||
}
|
||||
|
||||
/* activate interface: interface_up returns 0 on success */
|
||||
flags = interface_up(ifinfo->ifname);
|
||||
if (flags == 0)
|
||||
ifinfo->state = IFS_DELAY;
|
||||
else if (flags == IFS_TENTATIVE)
|
||||
ifinfo->state = IFS_TENTATIVE;
|
||||
else
|
||||
ifinfo->state = IFS_DOWN;
|
||||
|
||||
rtsol_timer_update(ifinfo);
|
||||
|
||||
/* link into chain */
|
||||
if (iflist)
|
||||
ifinfo->next = iflist;
|
||||
iflist = ifinfo;
|
||||
|
||||
return(0);
|
||||
|
||||
bad:
|
||||
free(ifinfo);
|
||||
free(ifinfo->sdl);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
struct ifinfo *
|
||||
find_ifinfo(int ifindex)
|
||||
{
|
||||
struct ifinfo *ifi;
|
||||
|
||||
for (ifi = iflist; ifi; ifi = ifi->next)
|
||||
if (ifi->sdl->sdl_index == ifindex)
|
||||
return(ifi);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
make_packet(struct ifinfo *ifinfo)
|
||||
{
|
||||
char *buf;
|
||||
struct nd_router_solicit *rs;
|
||||
size_t packlen = sizeof(struct nd_router_solicit), lladdroptlen = 0;
|
||||
|
||||
if ((lladdroptlen = lladdropt_length(ifinfo->sdl)) == 0) {
|
||||
warnmsg(LOG_INFO, __FUNCTION__,
|
||||
"link-layer address option has null length"
|
||||
" on %s. Treat as not included.", ifinfo->ifname);
|
||||
}
|
||||
packlen += lladdroptlen;
|
||||
ifinfo->rs_datalen = packlen;
|
||||
|
||||
/* allocate buffer */
|
||||
if ((buf = malloc(packlen)) == NULL) {
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"memory allocation failed for %s", ifinfo->ifname);
|
||||
return(-1);
|
||||
}
|
||||
ifinfo->rs_data = buf;
|
||||
|
||||
/* fill in the message */
|
||||
rs = (struct nd_router_solicit *)buf;
|
||||
rs->nd_rs_type = ND_ROUTER_SOLICIT;
|
||||
rs->nd_rs_code = 0;
|
||||
rs->nd_rs_cksum = 0;
|
||||
rs->nd_rs_reserved = 0;
|
||||
buf += sizeof(*rs);
|
||||
|
||||
/* fill in source link-layer address option */
|
||||
if (lladdroptlen)
|
||||
lladdropt_fill(ifinfo->sdl, (struct nd_opt_hdr *)buf);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static struct timeval *
|
||||
rtsol_check_timer()
|
||||
{
|
||||
static struct timeval returnval;
|
||||
struct timeval now, rtsol_timer;
|
||||
struct ifinfo *ifinfo;
|
||||
int flags;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
rtsol_timer = tm_max;
|
||||
|
||||
for (ifinfo = iflist; ifinfo; ifinfo = ifinfo->next) {
|
||||
if (TIMEVAL_LEQ(ifinfo->expire, now)) {
|
||||
if (dflag > 1)
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__,
|
||||
"timer expiration on %s, "
|
||||
"state = %d", ifinfo->ifname,
|
||||
ifinfo->state);
|
||||
|
||||
switch(ifinfo->state) {
|
||||
case IFS_DOWN:
|
||||
case IFS_TENTATIVE:
|
||||
/* interface_up returns 0 on success */
|
||||
flags = interface_up(ifinfo->ifname);
|
||||
if (flags == 0)
|
||||
ifinfo->state = IFS_DELAY;
|
||||
else if (flags == IFS_TENTATIVE)
|
||||
ifinfo->state = IFS_TENTATIVE;
|
||||
else
|
||||
ifinfo->state = IFS_DOWN;
|
||||
break;
|
||||
case IFS_IDLE:
|
||||
{
|
||||
int oldstatus = ifinfo->active;
|
||||
int probe = 0;
|
||||
|
||||
ifinfo->active =
|
||||
interface_status(ifinfo);
|
||||
|
||||
if (oldstatus != ifinfo->active) {
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__,
|
||||
"%s status is changed"
|
||||
" from %d to %d",
|
||||
ifinfo->ifname,
|
||||
oldstatus, ifinfo->active);
|
||||
probe = 1;
|
||||
ifinfo->state = IFS_DELAY;
|
||||
}
|
||||
else if (ifinfo->probeinterval &&
|
||||
(ifinfo->probetimer -=
|
||||
ifinfo->timer.tv_sec) <= 0) {
|
||||
/* probe timer expired */
|
||||
ifinfo->probetimer =
|
||||
ifinfo->probeinterval;
|
||||
probe = 1;
|
||||
ifinfo->state = IFS_PROBE;
|
||||
}
|
||||
|
||||
if (probe && mobile_node)
|
||||
defrouter_probe(ifinfo->sdl->sdl_index);
|
||||
break;
|
||||
}
|
||||
case IFS_DELAY:
|
||||
ifinfo->state = IFS_PROBE;
|
||||
sendpacket(ifinfo);
|
||||
break;
|
||||
case IFS_PROBE:
|
||||
if (ifinfo->probes < MAX_RTR_SOLICITATIONS)
|
||||
sendpacket(ifinfo);
|
||||
else {
|
||||
warnmsg(LOG_INFO, __FUNCTION__,
|
||||
"No answer "
|
||||
"after sending %d RSs",
|
||||
ifinfo->probes);
|
||||
ifinfo->probes = 0;
|
||||
ifinfo->state = IFS_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
rtsol_timer_update(ifinfo);
|
||||
}
|
||||
|
||||
if (TIMEVAL_LT(ifinfo->expire, rtsol_timer))
|
||||
rtsol_timer = ifinfo->expire;
|
||||
}
|
||||
|
||||
if (TIMEVAL_EQ(rtsol_timer, tm_max)) {
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__, "there is no timer");
|
||||
return(NULL);
|
||||
}
|
||||
else if (TIMEVAL_LT(rtsol_timer, now))
|
||||
/* this may occur when the interval is too small */
|
||||
returnval.tv_sec = returnval.tv_usec = 0;
|
||||
else
|
||||
TIMEVAL_SUB(&rtsol_timer, &now, &returnval);
|
||||
|
||||
if (dflag > 1)
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__, "New timer is %d:%08d",
|
||||
returnval.tv_sec, returnval.tv_usec);
|
||||
|
||||
return(&returnval);
|
||||
}
|
||||
|
||||
void
|
||||
rtsol_timer_update(struct ifinfo *ifinfo)
|
||||
{
|
||||
#define MILLION 1000000
|
||||
#define DADRETRY 10 /* XXX: adhoc */
|
||||
long interval;
|
||||
struct timeval now;
|
||||
|
||||
bzero(&ifinfo->timer, sizeof(ifinfo->timer));
|
||||
|
||||
switch (ifinfo->state) {
|
||||
case IFS_DOWN:
|
||||
case IFS_TENTATIVE:
|
||||
if (++ifinfo->dadcount > DADRETRY) {
|
||||
ifinfo->dadcount = 0;
|
||||
ifinfo->timer.tv_sec = PROBE_INTERVAL;
|
||||
}
|
||||
else
|
||||
ifinfo->timer.tv_sec = 1;
|
||||
break;
|
||||
case IFS_IDLE:
|
||||
if (mobile_node) {
|
||||
/* XXX should be configurable */
|
||||
ifinfo->timer.tv_sec = 3;
|
||||
}
|
||||
else
|
||||
ifinfo->timer = tm_max; /* stop timer(valid?) */
|
||||
break;
|
||||
case IFS_DELAY:
|
||||
interval = random() % (MAX_RTR_SOLICITATION_DELAY * MILLION);
|
||||
ifinfo->timer.tv_sec = interval / MILLION;
|
||||
ifinfo->timer.tv_usec = interval % MILLION;
|
||||
break;
|
||||
case IFS_PROBE:
|
||||
ifinfo->timer.tv_sec = RTR_SOLICITATION_INTERVAL;
|
||||
break;
|
||||
default:
|
||||
warnmsg(LOG_ERR, __FUNCTION__,
|
||||
"illegal interface state(%d) on %s",
|
||||
ifinfo->state, ifinfo->ifname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* reset the timer */
|
||||
if (TIMEVAL_EQ(ifinfo->timer, tm_max)) {
|
||||
ifinfo->expire = tm_max;
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__,
|
||||
"stop timer for %s", ifinfo->ifname);
|
||||
}
|
||||
else {
|
||||
gettimeofday(&now, NULL);
|
||||
TIMEVAL_ADD(&now, &ifinfo->timer, &ifinfo->expire);
|
||||
|
||||
if (dflag > 1)
|
||||
warnmsg(LOG_DEBUG, __FUNCTION__,
|
||||
"set timer for %s to %d:%d", ifinfo->ifname,
|
||||
(int)ifinfo->timer.tv_sec,
|
||||
(int)ifinfo->timer.tv_usec);
|
||||
}
|
||||
|
||||
#undef MILLION
|
||||
}
|
||||
|
||||
/* timer related utility functions */
|
||||
#define MILLION 1000000
|
||||
|
||||
/* result = a + b */
|
||||
static void
|
||||
TIMEVAL_ADD(struct timeval *a, struct timeval *b, struct timeval *result)
|
||||
{
|
||||
long l;
|
||||
|
||||
if ((l = a->tv_usec + b->tv_usec) < MILLION) {
|
||||
result->tv_usec = l;
|
||||
result->tv_sec = a->tv_sec + b->tv_sec;
|
||||
}
|
||||
else {
|
||||
result->tv_usec = l - MILLION;
|
||||
result->tv_sec = a->tv_sec + b->tv_sec + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* result = a - b
|
||||
* XXX: this function assumes that a >= b.
|
||||
*/
|
||||
void
|
||||
TIMEVAL_SUB(struct timeval *a, struct timeval *b, struct timeval *result)
|
||||
{
|
||||
long l;
|
||||
|
||||
if ((l = a->tv_usec - b->tv_usec) >= 0) {
|
||||
result->tv_usec = l;
|
||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||
}
|
||||
else {
|
||||
result->tv_usec = MILLION + l;
|
||||
result->tv_sec = a->tv_sec - b->tv_sec - 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rtsold_set_dump_file()
|
||||
{
|
||||
do_dump = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
if (progname && progname[strlen(progname) - 1] != 'd')
|
||||
fprintf(stderr, "usage: rtsol [-dD] interfaces\n");
|
||||
else
|
||||
fprintf(stderr, "usage: rtsold [-dDfm1] interfaces\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
warnmsg(int priority, const char *func, const char *msg, ...)
|
||||
#else
|
||||
warnmsg(priority, func, msg, va_alist)
|
||||
int priority;
|
||||
const char *func;
|
||||
const char *msg;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list ap;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
va_start(ap, msg);
|
||||
if (fflag) {
|
||||
if (priority <= log_upto) {
|
||||
(void)vfprintf(stderr, msg, ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
}
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "<%s> %s", func, msg);
|
||||
vsyslog(priority, buf, ap);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
91
usr.sbin/rtsold/rtsold.h
Normal file
91
usr.sbin/rtsold/rtsold.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 project 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 PROJECT 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 PROJECT 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct ifinfo {
|
||||
struct ifinfo *next; /* pointer to the next interface */
|
||||
|
||||
struct sockaddr_dl *sdl; /* link-layer address */
|
||||
char ifname[16]; /* interface name */
|
||||
int active; /* interface status */
|
||||
int probeinterval; /* interval of probe timer(if necessary) */
|
||||
int probetimer; /* rest of probe timer */
|
||||
int mediareqok; /* wheter the IF supports SIOCGIFMEDIA */
|
||||
int state;
|
||||
int probes;
|
||||
int dadcount;
|
||||
struct timeval timer;
|
||||
struct timeval expire;
|
||||
|
||||
int racnt; /* total # of valid RAs it have got */
|
||||
|
||||
size_t rs_datalen;
|
||||
u_char *rs_data;
|
||||
};
|
||||
|
||||
/* per interface status */
|
||||
#define IFS_IDLE 0
|
||||
#define IFS_DELAY 1
|
||||
#define IFS_PROBE 2
|
||||
#define IFS_DOWN 3
|
||||
#define IFS_TENTATIVE 4
|
||||
|
||||
/* rtsold.c */
|
||||
extern struct timeval tm_max;
|
||||
extern int dflag;
|
||||
struct ifinfo *find_ifinfo __P((int ifindex));
|
||||
void rtsol_timer_update __P((struct ifinfo *ifinfo));
|
||||
#ifdef __STDC__
|
||||
extern void warnmsg __P((int, const char *, const char *, ...));
|
||||
#else
|
||||
extern void warnmsg __P((int, const char *, const char *, va_list));
|
||||
#endif
|
||||
|
||||
/* if.c */
|
||||
extern int ifinit __P((void));
|
||||
extern int interface_up __P((char *name));
|
||||
extern int interface_status __P((struct ifinfo*));
|
||||
extern int lladdropt_length __P((struct sockaddr_dl *sdl));
|
||||
extern void lladdropt_fill __P((struct sockaddr_dl *sdl,
|
||||
struct nd_opt_hdr *ndopt));
|
||||
extern struct sockaddr_dl *if_nametosdl __P((char *name));
|
||||
extern int getinet6sysctl __P((int code));
|
||||
|
||||
/* rtsol.c */
|
||||
extern int sockopen __P((void));
|
||||
extern void sendpacket __P((struct ifinfo *ifinfo));
|
||||
extern void rtsol_input __P((int s));
|
||||
|
||||
/* probe.c */
|
||||
extern int probe_init __P((void));
|
||||
extern void defrouter_probe __P((int ifindex));
|
||||
|
||||
/* dump.c */
|
||||
extern void rtsold_dump_file __P((char *));
|
26
usr.sbin/traceroute6/Makefile
Normal file
26
usr.sbin/traceroute6/Makefile
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (c) 1996 WIDE Project. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modifications, are permitted provided that the above copyright notice
|
||||
# and this paragraph are duplicated in all such forms and that any
|
||||
# documentation, advertising materials, and other materials related to
|
||||
# such distribution and use acknowledge that the software was developed
|
||||
# by the WIDE Project, Japan. The name of the Project may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS''
|
||||
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE.
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= traceroute6
|
||||
|
||||
BINOWN= root
|
||||
BINGRP= bin
|
||||
BINMODE=4555
|
||||
|
||||
CFLAGS+=-DINET6
|
||||
|
||||
MAN8= traceroute6.8
|
||||
|
||||
.include <bsd.prog.mk>
|
96
usr.sbin/traceroute6/traceroute6.8
Normal file
96
usr.sbin/traceroute6/traceroute6.8
Normal file
@ -0,0 +1,96 @@
|
||||
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
.\" 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 project 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 PROJECT 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 PROJECT 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.
|
||||
.\"
|
||||
.\" $Id: traceroute6.8,v 1.1.1.1 1999/08/08 23:32:38 itojun Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 17, 1998
|
||||
.Dt TRACEROUTE6 8
|
||||
.Os KAME
|
||||
.\"
|
||||
.Sh NAME
|
||||
.Nm traceroute6
|
||||
.Nd print the route IPv6 packets will take to the destination
|
||||
.\"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl dlnrv
|
||||
.Op Fl m Ar hoplimit
|
||||
.Op Fl p Ar port
|
||||
.Op Fl q Ar probes
|
||||
.Op Fl s Ar src
|
||||
.Op Fl w Ar waittime
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -width Ds
|
||||
.It Fl d
|
||||
Debug mode.
|
||||
.It Fl m Ar hoplimit
|
||||
Specify maximum hoplimit.
|
||||
.It Fl l
|
||||
Print both host hostnames and numeric addresses.
|
||||
Normally
|
||||
.Nm
|
||||
prints only hostnames if
|
||||
.Fl n
|
||||
is not specified, and only numeric addresses if
|
||||
.Fl n
|
||||
is specified.
|
||||
.It Fl n
|
||||
Do not resolve numeric address to hostname.
|
||||
.It Fl p Ar port
|
||||
Set UDP port number to
|
||||
.Ar port .
|
||||
.It Fl q Ar probes
|
||||
Set the number of probe per hop count to
|
||||
.Ar probes .
|
||||
.It Fl r
|
||||
.It Fl s Ar src
|
||||
.Ar Src
|
||||
specifies the source IPv6 address to be used.
|
||||
.It Fl v
|
||||
Be verbose.
|
||||
.It Fl w Ar waittime
|
||||
Specify the delay time between probes.
|
||||
.El
|
||||
.\"
|
||||
.Sh RETURN VALUES
|
||||
.Nm Traceroute6
|
||||
will exit with 0 on success, and non-zero on errors.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr ping 8 ,
|
||||
.Xr ping6 8 ,
|
||||
.Xr traceroute 8
|
||||
.\"
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command first appeared in WIDE hydrangea IPv6 protocol stack kit.
|
||||
.\"
|
||||
.\" .Sh BUGS
|
||||
.\" (to be written)
|
1127
usr.sbin/traceroute6/traceroute6.c
Normal file
1127
usr.sbin/traceroute6/traceroute6.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user