diff options
| author | Kris Kennaway <kris@FreeBSD.org> | 2000-07-15 07:38:52 +0000 |
|---|---|---|
| committer | Kris Kennaway <kris@FreeBSD.org> | 2000-07-15 07:38:52 +0000 |
| commit | 5bc9481d421fc39eb90f9ec940d1190dc58c188d (patch) | |
| tree | 06840d1fbb43b8bf9b09df9987de546a67bd7416 /usr.sbin | |
| parent | e6d0854e13b64e40140480e08569e93f3c6b93cb (diff) | |
Notes
Diffstat (limited to 'usr.sbin')
155 files changed, 6888 insertions, 5169 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 055ec7818c803..e15c4e1cbd7e3 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -45,6 +45,7 @@ SUBDIR= IPXrouted \ memcontrol \ mergemaster \ mixer \ + mld6query \ mlxcontrol \ moused \ mrouted \ diff --git a/usr.sbin/faithd/Makefile b/usr.sbin/faithd/Makefile index c40c21de0c44f..8defe63d7cfd4 100644 --- a/usr.sbin/faithd/Makefile +++ b/usr.sbin/faithd/Makefile @@ -18,7 +18,7 @@ SRCS= faithd.c tcp.c ftp.c rsh.c MAN8= faithd.8 #CFLAGS+= -DFAITH4 CFLAGS+= -Wall -DPADD+= ${LIBUTIL} -LDADD+= -lutil +DPADD= ${LIBUTIL} +LDADD= -lutil .include <bsd.prog.mk> diff --git a/usr.sbin/faithd/README b/usr.sbin/faithd/README index 47d7a2d690f20..4808b4af25442 100644 --- a/usr.sbin/faithd/README +++ b/usr.sbin/faithd/README @@ -1,14 +1,13 @@ Configuring FAITH IPv6-to-IPv4 TCP relay Kazu Yamamoto and Jun-ichiro itojun Hagino -$Id: README,v 1.1.1.1 1999/08/08 23:29:27 itojun Exp $ +$KAME: README,v 1.4 2000/05/31 03:16:14 itojun Exp $ $FreeBSD$ - Introduction ============ -FAITH is a IPv6-to-IPv4 TCP relay. It performs TCP relay just as some of +FAITH is a IPv6-to-IPv4 TCP relay. It performs tcp relay just as some of firewall-oriented gateway does, but between IPv6 and IPv4 with address translation. TCP connections has to be made from IPv6 node to IPv4 node. FAITH will @@ -34,7 +33,7 @@ FAITH will make it possible to make a IPv6 TCP connection From IPv6 node "src", toward IPv4 node "dest", by specifying FAITH-mapped address 3ffe:0501:1234:ffff::123.4.5.6 (which is, 3ffe:0501:1234:ffff:0000:0000:7b04:0506). -The address mapping can be performed by hand:-), by special nameserver on +The address mapping can be performed by hand:-), by speical nameserver on the network, or by special resolver on the source node. @@ -42,7 +41,7 @@ Setup ===== The following example assumes: -- You have assigned 3ffe:0501:1234:ffff:: as FAITH address prefix. +- You have assigned 3ffe:0501:1234:ffff:: as FAITH adderss prefix. - You are willing to provide IPv6-to IPv4 TCP relay for telnet. <<On the translating router on which faithd runs>> @@ -58,13 +57,8 @@ The following example assumes: (3) Route packets toward FAITH prefix into "faith0" interface. # ifconfig faith0 up - # route add -inet6 3ffe:0501:1234:ffff:: -prefixlen 64 -interface faith0 - - or, on platforms that has problem with "-interface": - # ifconfig faith0 up # route add -inet6 3ffe:0501:1234:ffff:: -prefixlen 64 \ - fe80:q::xxxx:yyyy:zzzz:wwww - (the last one is link-local address assigned for faith0) + fe80::xxxx:yyyy:zzzz:wwww%faith0 (4) Execute "faithd" by root as follows: @@ -82,7 +76,7 @@ The following example assumes: # faithd login /usr/local/v6/libexec/rlogin rlogind # faithd shell /usr/local/v6/libexec/rshd rshd # faithd ftpd /usr/local/v6/libexec/ftpd ftpd -l - # faithd ssh + # faithd sshd <<Routing>> @@ -96,13 +90,12 @@ There are two ways to translate IPv4 address to IPv6 address: (a) Faked by DNS (b) Faked by /etc/hosts. -(5.a) Install "newbie" and set up FAITH mode. See kit/ports/newbie of - KAME package. KAME package is obtained from www.kame.net. +(5.a) Install "newbie" and set up FAITH mode. See kit/ports/newbie. (5.b) Add an entry into /etc/hosts so that you can resolve hostname into -faked IPv6 address. For example, add the following line for www.freebsd.org: +faked IPv6 addrss. For example, add the following line for www.netbsd.org: - 3ffe:0501:1234:ffff::204.216.27.21 www.freebsd.org + 3ffe:0501:1234:ffff::140.160.140.252 www.netbsd.org <<On the translating router on which faithd runs.>> @@ -125,16 +118,16 @@ want to do the following: By this way, you can restrict IPv4 destination to 123.0.0.0/8. You may also want to reject packets toward 3ffe:0501:1234:ffff::/64 which -is not in 3ffe:0501:1234:ffff::123.0.0.0/104. This will be left as exercise +is not in 3ffe:0501:1234:ffff::123.0.0.0/104. This will be left as excerside for the reader. By doing this, you will be able to provide your IPv4 web server to outside IPv6 customers, without risks of unwanted open relays. - [[[[ IPv6 network outside ]]]] | + [[[[ IPv6 network outside ]]]] | | | connection node that runs FAITH-daemon (usually a router) v | - ========+======== IPv4/v6 network in your site + ========+======== IPv4/v6 network in your site | (123.0.0.0/8) IPv4 web server diff --git a/usr.sbin/faithd/faithd.8 b/usr.sbin/faithd/faithd.8 index 62c721a32aaec..6e42f27bd4452 100644 --- a/usr.sbin/faithd/faithd.8 +++ b/usr.sbin/faithd/faithd.8 @@ -1,6 +1,8 @@ +.\" $KAME: faithd.8,v 1.12 2000/07/04 13:15:01 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: @@ -12,7 +14,7 @@ .\" 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 @@ -25,10 +27,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: faithd.8,v 1.3 1999/10/07 04:22:14 itojun Exp $ .\" $FreeBSD$ .\" -.Dd January 27, 2000 +.Dd May 17, 1998 .Dt FAITHD 8 .Os .Sh NAME @@ -38,35 +39,18 @@ .Nm .Op Fl dp .Op Ar service Op Ar serverpath Op Ar serverargs +.Nm "" .Sh DESCRIPTION .Nm -provides IPv6/v4 TCP relay for the specified -.Ar service . -.Pp +provides IPv6-to-IPv4 TCP relay. .Nm -must be invoked on IPv4/v6 -dual stack router. -The router must be configured to capture all the TCP traffic -toward reserved -.Tn IPv6 -address prefix, by using -.Xr route 8 -and -.Xr sysctl 8 -commands. -.Nm -will daemonize itself on invocation. +must be used on an IPv4/v6 dual stack router. .Pp +When .Nm -will listen to +receives .Tn TCPv6 -port -.Ar service . -If -.Tn TCPv6 -traffic to port -.Ar service -is found, +traffic, .Nm will relay the .Tn TCPv6 @@ -88,20 +72,47 @@ destination address is the traffic will be relayed to IPv4 destination .Li 10.1.1.1 . .Pp -If -.Ar service -is not given, -.Li telnet -is assumed, and +To use .Nm -will relay TCP traffic on TCP port -.Li telnet . -With -.Ar service , +translation service, +an IPv6 address prefix must be reserved for mapping IPv4 addresses into. +Kernel must be properly configured to route all the TCP connection +toward the reserved IPv6 address prefix into the +.Xr faith 4 +pseudo interface, by using +.Xr route 8 +command. +Also, +.Xr sysctl 8 +should be used to configure +.Dv net.inet6.ip6.keepfaith +to +.Dv 1 . +.Pp +The router must be configured to capture all the TCP traffic +toward reserved +.Tn IPv6 +address prefix, by using +.Xr route 8 +and +.Xr sysctl 8 +commands. +.Ss Daemon mode +When .Nm -will work as TCP relaying daemon for specified +is invoked as a standalone program, +.Nm +will daemonize itself. +.Nm +will listen to +.Tn TCPv6 +port +.Ar service . +If +.Tn TCPv6 +traffic to port .Ar service -as described above. +is found, it relays the connection. .Pp Since .Nm @@ -126,22 +137,20 @@ You can also specify .Ar serverargs for the arguments for the local daemon. .Pp -To use +If +.Ar service +is not given, +.Li telnet +is assumed, and .Nm -translation service, -an IPv6 address prefix must be reserved for mapping IPv4 addresses into. -Kernel must be properly configured to route all the TCP connection -toward the reserved IPv6 address prefix into the -.Dv faith -pseudo interface, by using -.Xr route 8 -command. -Also, -.Xr sysctl 8 -should be used to configure -.Dv net.inet6.ip6.keepfaith -to -.Dv 1 . +will relay TCP traffic on TCP port +.Li telnet . +With +.Ar service , +.Nm +will work as TCP relaying daemon for specified +.Ar service +as described above. .Pp If .Fl d @@ -160,7 +169,7 @@ and .Fl p is not necessary as special program code is supplied. .Pp -.Nm +.Nm will relay both normal and out-of-band TCP data. It is capable of emulating TCP half close as well. .Nm @@ -187,12 +196,50 @@ Inactive sessions will be disconnected in 30 minutes, to avoid stale sessions from chewing up resources. This may be inappropriate for some of the services .Pq should this be configurable? . +.Ss inetd mode +When +.Nm +is invoked via +.Xr inetd 8 , +.Nm +will handle connection passed from standard input. +If it the connection endpoint is in the reserved IPv6 address prefix. +.Nm +will relay the connection. +Otherwise, +.Nm +will invoke service-specific daemon like +.Xr telnetd 8 , +by using the command argument passed from +.Xr inetd 8 . +.Pp +.Nm +determines operation mode by the local TCP port number, +and enables special protocol handling whenever necessary/possible. +For example, if +.Nm +is invoked via +.Xr inetd 8 +on FTP port, it will operate as a FTP relay. +.Pp +The operation mode requires special support for +.Nm +in +.Xr inetd 8 . .Sh EXAMPLES Before invoking .Nm Ns , .Xr faith 4 interface has to be configured properly. -.Pp +.Bd -literal -offset +# sysctl -w net.inet6.ip6.accept_rtadv=0 +# sysctl -w net.inet6.ip6.forwarding=1 +# sysctl -w net.inet6.ip6.keepfaith=1 +# ifconfig faith0 up +# route add -inet6 3ffe:501:4819:ffff:: -prefixlen 96 ::1 +# route change -inet6 3ffe:501:4819:ffff:: -prefixlen 96 -ifp faith0 +.Ed +.Ss Daemon mode samples To translate .Li telnet service, and provide no local telnet service, invoke @@ -200,29 +247,60 @@ service, and provide no local telnet service, invoke as either of the following: .Bd -literal -offset # faithd -# faithd telnet +# faithd telnet .Ed .Pp If you would like to provide local telnet service via .Xr telnetd 8 on -.Pa /usr/libexec/telnetd , -user the following command line: +.Pa /usr/local/v6/libexec/telnetd , +use the following command line: .Bd -literal -offset -# faithd telnet /usr/libexec/telnetd telnetd +# faithd telnet /usr/local/v6/libexec/telnetd telnetd .Ed .Pp If you would like to pass extra arguments to the local daemon: .Bd -literal -offset -# faithd ftpd /usr/libexec/ftpd ftpd -l +# faithd ftpd /usr/local/v6/libexec/ftpd ftpd -l .Ed .Pp -Here are some other examples: +Here are some other examples. +You may need +.Fl p +to translate rsh/rlogin services. .Bd -literal -offset -# faithd login /usr/libexec/rlogin rlogind -# faithd shell /usr/libexec/rshd rshd # faithd sshd +# faithd login /usr/local/v6/libexec/rlogin rlogind +# faithd shell /usr/local/v6/libexec/rshd rshd .Ed +.Pp +However, you should be careful when translating rlogin or rsh +connections. See +.Sx SECURITY NOTICE +for more details. +.Ss inetd mode samples +Add the following lines into +.Xr inetd.conf 5 . +Syntax may vary depending upon your operating system. +.Bd -literal -offset +telnet stream faith/tcp6 nowait root faithd telnetd +ftp stream faith/tcp6 nowait root faithd ftpd -l +ssh stream faith/tcp6 nowait root faithd /usr/pkg/bin/sshd -i +.Ed +.Pp +.Xr inetd 8 +will open listening sockets with enabling kernel TCP relay support. +Whenever connection comes in, +.Nm +will be invoked by +.Xr inetd 8 . +If it the connection endpoint is in the reserved IPv6 address prefix. +.Nm +will relay the connection. +Otherwise, +.Nm +will invoke service-specific daemon like +.Xr telnetd 8 . .Sh RETURN VALUES .Nm exits with @@ -240,8 +318,8 @@ on error. .%A Jun-ichiro itojun Hagino .%A Kazu Yamamoto .%T "An IPv6-to-IPv4 transport relay translator" -.%R Internet draft -.%N draft-ietf-ngtrans-tcpudp-relay-00.txt +.%R internet draft +.%N draft-ietf-ngtrans-tcpudp-relay-01.txt .%O work in progress material .Re .Sh SECURITY NOTICE @@ -250,6 +328,21 @@ It is very insecure to use and other IP-address based authentication, for connections relayed by .Nm .Pq and any other TCP relaying services . +.Pp +.Nm +itself does not implement access controls, as +it intends to implement transparent TCP relay services. +Administrators are advised to filter packets based on IPv6 address. +IPv6 destination address can be limited by +carefully configuring routing entries that points to +.Xr faith 4 , +using +.Xr route 8 . +IPv6 source address needs to be filtered by using packet filters. +Documents listed in +.Sx SEE ALSO +have more discussions on this topic. +.\" .Sh HISTORY The .Nm diff --git a/usr.sbin/faithd/faithd.c b/usr.sbin/faithd/faithd.c index 6f90d872f8532..c314b74bea49e 100644 --- a/usr.sbin/faithd/faithd.c +++ b/usr.sbin/faithd/faithd.c @@ -1,7 +1,9 @@ +/* $KAME: faithd.c,v 1.20 2000/07/01 11:40:45 itojun Exp $ */ + /* * Copyright (C) 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: @@ -13,7 +15,7 @@ * 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 @@ -35,6 +37,7 @@ * Usage: faithd [<port> <progpath> <arg1(progname)> <arg2> ...] * e.g. faithd telnet /usr/local/v6/sbin/telnetd telnetd */ +#define HAVE_GETIFADDRS #include <sys/param.h> #include <sys/types.h> @@ -44,7 +47,9 @@ #include <sys/stat.h> #include <sys/time.h> #include <sys/ioctl.h> +#ifdef __FreeBSD__ #include <libutil.h> +#endif #include <stdio.h> #include <stdlib.h> @@ -68,6 +73,9 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> +#ifdef HAVE_GETIFADDRS +#include <ifaddrs.h> +#endif #ifdef FAITH4 #include <resolv.h> @@ -95,8 +103,11 @@ static int sockfd = 0; #endif int dflag = 0; static int pflag = 0; +static int inetd = 0; int main __P((int, char **)); +static int inetd_main __P((int, char **)); +static int daemon_main __P((int, char **)); static void play_service __P((int)); static void play_child __P((int, struct sockaddr *)); static int faith_prefix __P((struct sockaddr *)); @@ -107,24 +118,17 @@ static int map4to6 __P((struct sockaddr_in *, struct sockaddr_in6 *)); static void sig_child __P((int)); static void sig_terminate __P((int)); static void start_daemon __P((void)); +#ifndef HAVE_GETIFADDRS static unsigned int if_maxindex __P((void)); +#endif static void grab_myaddrs __P((void)); static void free_myaddrs __P((void)); static void update_myaddrs __P((void)); static void usage __P((void)); int -main(int argc, char *argv[]) +main(int argc, char **argv) { - struct addrinfo hints, *res; - int s_wld, error, i, serverargc, on = 1; - int family = AF_INET6; - int c; -#ifdef FAITH_NS - char *ns; -#endif /* FAITH_NS */ - extern int optind; - extern char *optarg; /* * Initializing stuff @@ -136,6 +140,87 @@ main(int argc, char *argv[]) else faithdname = argv[0]; + if (strcmp(faithdname, "faithd") != 0) { + inetd = 1; + return inetd_main(argc, argv); + } else + return daemon_main(argc, argv); +} + +static int +inetd_main(int argc, char **argv) +{ + char path[MAXPATHLEN]; + struct sockaddr_storage me; + struct sockaddr_storage from; + int melen, fromlen; + int i; + int error; + const int on = 1; + char sbuf[NI_MAXSERV], snum[NI_MAXSERV]; + + if (strrchr(argv[0], '/') == NULL) + snprintf(path, sizeof(path), "%s/%s", DEFAULT_DIR, argv[0]); + else + snprintf(path, sizeof(path), "%s", argv[0]); + +#ifdef USE_ROUTE + grab_myaddrs(); + + sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); + if (sockfd < 0) { + exit_error("socket(PF_ROUTE): %s", ERRSTR); + /*NOTREACHED*/ + } +#endif + + melen = sizeof(me); + if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0) + exit_error("getsockname"); + fromlen = sizeof(from); + if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0) + exit_error("getpeername"); + if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, + sbuf, sizeof(sbuf), NI_NUMERICHOST) == 0) + service = sbuf; + else + service = DEFAULT_PORT_NAME; + if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, + snum, sizeof(snum), NI_NUMERICHOST) != 0) + snprintf(snum, sizeof(snum), "?"); + + snprintf(logname, sizeof(logname), "faithd %s", snum); + snprintf(procname, sizeof(procname), "accepting port %s", snum); + openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); + + if (argc >= MAXARGV) + exit_failure("too many augments"); + serverarg[0] = serverpath = path; + for (i = 1; i < argc; i++) + serverarg[i] = argv[i]; + serverarg[i] = NULL; + + error = setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &on, + sizeof(on)); + if (error < 0) + exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR); + + play_child(STDIN_FILENO, (struct sockaddr *)&from); + exit_failure("should not reach here"); + return 0; /*dummy!*/ +} + +static int +daemon_main(int argc, char **argv) +{ + struct addrinfo hints, *res; + int s_wld, error, i, serverargc, on = 1; + int family = AF_INET6; + int c; +#ifdef FAITH_NS + char *ns; +#endif /* FAITH_NS */ + while ((c = getopt(argc, argv, "dp46")) != -1) { switch (c) { case 'd': @@ -191,17 +276,17 @@ main(int argc, char *argv[]) break; default: serverargc = argc - NUMARG; - if (serverargc > MAXARGV) - exit_error("too many arguments"); + if (serverargc >= MAXARGV) + exit_error("too many augments"); - serverpath = malloc(strlen(argv[NUMPRG])); + serverpath = malloc(strlen(argv[NUMPRG]) + 1); strcpy(serverpath, argv[NUMPRG]); for (i = 0; i < serverargc; i++) { - serverarg[i] = malloc(strlen(argv[i + NUMARG])); + serverarg[i] = malloc(strlen(argv[i + NUMARG]) + 1); strcpy(serverarg[i], argv[i + NUMARG]); } serverarg[i] = NULL; - /* FALLTHROUGH */ + /* fall throuth */ case 1: /* no local service */ service = argv[NUMPRT]; break; @@ -217,12 +302,8 @@ main(int argc, char *argv[]) hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; error = getaddrinfo(NULL, service, &hints, &res); - if (error) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error)); - if (error == EAI_SYSTEM) - exit_error("getaddrinfo: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } + if (error) + exit_error("getaddrinfo: %s", gai_strerror(error)); s_wld = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s_wld == -1) @@ -278,10 +359,10 @@ main(int argc, char *argv[]) snprintf(logname, sizeof(logname), "faithd %s", service); snprintf(procname, sizeof(procname), "accepting port %s", service); openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); - syslog(LOG_INFO, "starting faith daemon for %s port", service); + syslog(LOG_INFO, "Staring faith daemon for %s port", service); play_service(s_wld); - /*NOTREACHED*/ + /*NOTRECHED*/ exit(1); /*pacify gcc*/ } @@ -354,7 +435,7 @@ again: static void play_child(int s_src, struct sockaddr *srcaddr) { - struct sockaddr_storage dstaddr6; + struct sockaddr_storage dstaddr6; struct sockaddr_storage dstaddr4; char src[MAXHOSTNAMELEN]; char dst6[MAXHOSTNAMELEN]; @@ -385,10 +466,12 @@ play_child(int s_src, struct sockaddr *srcaddr) * Local service */ syslog(LOG_INFO, "executing local %s", serverpath); - dup2(s_src, 0); - close(s_src); - dup2(0, 1); - dup2(0, 2); + if (!inetd) { + dup2(s_src, 0); + close(s_src); + dup2(0, 1); + dup2(0, 2); + } execv(serverpath, serverarg); syslog(LOG_ERR, "execv %s: %s", serverpath, ERRSTR); _exit(EXIT_FAILURE); @@ -597,9 +680,6 @@ map4to6(struct sockaddr_in *dst4, struct sockaddr_in6 *dst6) if ((ai_errno = getaddrinfo(host, serv, &hints, &res)) != 0) { syslog(LOG_INFO, "%s %s: %s", host, serv, gai_strerror(ai_errno)); - if (ai_errno == EAI_SYSTEM) - syslog(LOG_INFO, "%s %s: %s", host, serv, - strerror(errno)); return 0; } @@ -625,7 +705,7 @@ sig_child(int sig) void sig_terminate(int sig) { - syslog(LOG_INFO, "terminating faith daemon"); + syslog(LOG_INFO, "Terminating faith daemon"); exit(EXIT_SUCCESS); } @@ -664,7 +744,7 @@ exit_failure(const char *fmt, ...) va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - syslog(LOG_ERR, buf); + syslog(LOG_ERR, "%s", buf); exit(EXIT_FAILURE); } @@ -677,11 +757,12 @@ exit_success(const char *fmt, ...) va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - syslog(LOG_INFO, buf); + syslog(LOG_INFO, "%s", buf); exit(EXIT_SUCCESS); } #ifdef USE_ROUTE +#ifndef HAVE_GETIFADDRS static unsigned int if_maxindex() { @@ -696,17 +777,73 @@ if_maxindex() if_freenameindex(p0); return max; } +#endif static void grab_myaddrs() { +#ifdef HAVE_GETIFADDRS + struct ifaddrs *ifap, *ifa; + struct myaddrs *p; + struct sockaddr_in6 *sin6; + + if (getifaddrs(&ifap) != 0) { + exit_failure("getifaddrs"); + /*NOTREACHED*/ + } + + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + switch (ifa->ifa_addr->sa_family) { + case AF_INET: + case AF_INET6: + break; + default: + continue; + } + + p = (struct myaddrs *)malloc(sizeof(struct myaddrs) + + ifa->ifa_addr->sa_len); + if (!p) { + exit_failure("not enough core"); + /*NOTREACHED*/ + } + memcpy(p + 1, ifa->ifa_addr, ifa->ifa_addr->sa_len); + p->next = myaddrs; + p->addr = (struct sockaddr *)(p + 1); +#ifdef __KAME__ + if (ifa->ifa_addr->sa_family == AF_INET6) { + sin6 = (struct sockaddr_in6 *)p->addr; + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) + || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { + sin6->sin6_scope_id = + ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); + sin6->sin6_addr.s6_addr[2] = 0; + sin6->sin6_addr.s6_addr[3] = 0; + } + } +#endif + myaddrs = p; + if (dflag) { + char hbuf[NI_MAXHOST]; + getnameinfo(p->addr, p->addr->sa_len, + hbuf, sizeof(hbuf), NULL, 0, + NI_NUMERICHOST); + syslog(LOG_INFO, "my interface: %s %s", hbuf, + ifa->ifa_name); + } + } + + freeifaddrs(ifap); +#else int s; unsigned int maxif; struct ifreq *iflist; struct ifconf ifconf; - struct ifreq *ifr, *ifr_end; + struct ifreq *ifr, *ifrp, *ifr_end; struct myaddrs *p; struct sockaddr_in6 *sin6; + size_t siz; + char ifrbuf[sizeof(struct ifreq) + 1024]; maxif = if_maxindex() + 1; iflist = (struct ifreq *)malloc(maxif * BUFSIZ); /* XXX */ @@ -730,10 +867,21 @@ grab_myaddrs() /* Look for this interface in the list */ ifr_end = (struct ifreq *) (ifconf.ifc_buf + ifconf.ifc_len); - for (ifr = ifconf.ifc_req; - ifr < ifr_end; - ifr = (struct ifreq *) ((char *) &ifr->ifr_addr - + ifr->ifr_addr.sa_len)) { + for (ifrp = ifconf.ifc_req; + ifrp < ifr_end; + ifrp = (struct ifreq *)((char *)ifrp + siz)) { + memcpy(ifrbuf, ifrp, sizeof(*ifrp)); + ifr = (struct ifreq *)ifrbuf; + siz = ifr->ifr_addr.sa_len; + if (siz < sizeof(ifr->ifr_addr)) + siz = sizeof(ifr->ifr_addr); + siz += (sizeof(*ifrp) - sizeof(ifr->ifr_addr)); + if (siz > sizeof(ifrbuf)) { + /* ifr too big */ + break; + } + memcpy(ifrbuf, ifrp, siz); + switch (ifr->ifr_addr.sa_family) { case AF_INET: case AF_INET6: @@ -773,6 +921,7 @@ grab_myaddrs() } free(iflist); +#endif } static void diff --git a/usr.sbin/faithd/faithd.h b/usr.sbin/faithd/faithd.h index 55566edc030c0..b882aad9bb71a 100644 --- a/usr.sbin/faithd/faithd.h +++ b/usr.sbin/faithd/faithd.h @@ -1,7 +1,9 @@ +/* $KAME: faithd.h,v 1.2 2000/05/31 03:06:07 itojun Exp $ */ + /* * Copyright (C) 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: @@ -13,7 +15,7 @@ * 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 @@ -43,8 +45,9 @@ extern void exit_success __P((const char *fmt, ...)); extern void exit_failure __P((const char *fmt, ...)); #define DEFAULT_PORT_NAME "telnet" -#define DEFAULT_PATH "/usr/local/v6/libexec/telnetd" +#define DEFAULT_DIR "/usr/local/v6/libexec" #define DEFAULT_NAME "telnetd" +#define DEFAULT_PATH (DEFAULT_DIR "/" DEFAULT_NAME) #define FTP_PORT 21 #define RLOGIN_PORT 513 diff --git a/usr.sbin/faithd/ftp.c b/usr.sbin/faithd/ftp.c index b45017aeebb53..53f94f1203829 100644 --- a/usr.sbin/faithd/ftp.c +++ b/usr.sbin/faithd/ftp.c @@ -1,7 +1,9 @@ +/* $KAME$ */ + /* * Copyright (C) 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: @@ -13,7 +15,7 @@ * 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 @@ -405,7 +407,7 @@ ftp_copyresult(int src, int dst, enum state state) if (!passivemode && rbuf[0] == '1') { if (ftp_activeconn() < 0) { n = snprintf(rbuf, sizeof(rbuf), - "425 Cannot open data connection\r\n"); + "425 Cannot open data connetion\r\n"); } } write(dst, rbuf, n); @@ -555,10 +557,10 @@ passivefail: p = (char *)&sin6->sin6_port; n = snprintf(sbuf, sizeof(sbuf), "228 Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\r\n", - 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), - UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]), - UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]), - UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]), + 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), + UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]), + UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]), + UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]), 2, UC(p[0]), UC(p[1])); write(dst, sbuf, n); passivemode = 1; @@ -676,7 +678,7 @@ passivefail2: p = (char *)&sin->sin_port; n = snprintf(sbuf, sizeof(sbuf), "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n", - UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), + UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); write(dst, sbuf, n); passivemode = 1; @@ -921,12 +923,7 @@ eprtparamfail: error = getaddrinfo(hostp, portp, &hints, &res); if (error) { n = snprintf(sbuf, sizeof(sbuf), - "501 EPRT: %s", gai_strerror(error)); - if (error == EAI_SYSTEM) - n += snprintf(sbuf, sizeof(sbuf), - ": %s", strerror(errno)); - n += snprintf(sbuf, sizeof(sbuf), "\r\n"); - + "501 EPRT: %s\r\n", gai_strerror(error)); write(src, sbuf, n); return n; } diff --git a/usr.sbin/faithd/rsh.c b/usr.sbin/faithd/rsh.c index e66ced1ee8113..735f01e8812ed 100644 --- a/usr.sbin/faithd/rsh.c +++ b/usr.sbin/faithd/rsh.c @@ -1,7 +1,9 @@ +/* $KAME$ */ + /* * Copyright (C) 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: @@ -13,7 +15,7 @@ * 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 @@ -69,7 +71,7 @@ rsh_relay(int s_src, int s_dst) if (error == -1) exit_failure("select %d: %s", s_src, ERRSTR); else if (error == 0) - exit_failure("connection timeout"); + exit_failure("connecion timeout"); n = read(s_src, rshbuf, sizeof(rshbuf)); if (rshbuf[0] != 0) { @@ -112,7 +114,7 @@ relay(int src, int dst) close(dst); close(s_ctl); close(s_ctl6); - exit_success("terminating rsh/control connections"); + exit_success("terminating rsh/contorol connections"); break; default: write(s_snd, rshbuf, n); @@ -180,7 +182,7 @@ rsh_dual_relay(int s_src, int s_dst) if (error == -1) exit_failure("select 4 sockets: %s", ERRSTR); else if (error == 0) - exit_failure("connection timeout"); + exit_failure("connecion timeout"); if (half == NO && FD_ISSET(s_src, &readfds)) { s_rcv = s_src; diff --git a/usr.sbin/faithd/tcp.c b/usr.sbin/faithd/tcp.c index e1e1b328c2b10..004686fe97818 100644 --- a/usr.sbin/faithd/tcp.c +++ b/usr.sbin/faithd/tcp.c @@ -1,7 +1,9 @@ +/* $KAME$ */ + /* * Copyright (C) 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: @@ -13,7 +15,7 @@ * 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 diff --git a/usr.sbin/gifconfig/gifconfig.8 b/usr.sbin/gifconfig/gifconfig.8 index 37b036d93e9ba..6a4e491fd4ce2 100644 --- a/usr.sbin/gifconfig/gifconfig.8 +++ b/usr.sbin/gifconfig/gifconfig.8 @@ -1,6 +1,9 @@ +.\" $FreeBSD$ +.\" $KAME: gifconfig.8,v 1.5 2000/05/13 07:48:10 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: @@ -12,7 +15,7 @@ .\" 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 @@ -25,9 +28,6 @@ .\" 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 @@ -40,6 +40,9 @@ .Op Ar af .Op Ar physsrc physdest .Nm gifconfig +.Ar interface +.Ic delete +.Nm gifconfig .Fl a .Sh DESCRIPTION .Nm @@ -66,6 +69,14 @@ and will be treated as .Li inet if ommitted. .Pp +If a special argument +.Ic delete +is specified, +.Nm +just deletes the existing source and destination addresses on +.Ar interface . +If no outer addresses are specified, this usage has no effect. +.Pp .Nm takes the following optional argument: .Bl -tag -width Ds diff --git a/usr.sbin/gifconfig/gifconfig.c b/usr.sbin/gifconfig/gifconfig.c index 49d0ba0919382..d93d74104dafe 100644 --- a/usr.sbin/gifconfig/gifconfig.c +++ b/usr.sbin/gifconfig/gifconfig.c @@ -1,3 +1,6 @@ +/* $FreeBSD$ */ +/* $KAME: gifconfig.c,v 1.12 2000/05/22 05:50:43 itojun Exp $ */ + /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. @@ -29,8 +32,6 @@ * 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$ */ /* @@ -57,7 +58,9 @@ #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> @@ -91,9 +94,9 @@ int flags; int metric; int mtu; int setpsrc = 0; +int newaddr = 0; int s; kvm_t *kvmd; -extern int errno; #ifdef INET6 char ntop_buf[INET6_ADDRSTRLEN]; /*inet_ntop()*/ @@ -102,7 +105,9 @@ char ntop_buf[INET6_ADDRSTRLEN]; /*inet_ntop()*/ void setifpsrc __P((char *, int)); void setifpdst __P((char *, int)); void setifflags __P((char *, int)); - +#ifdef SIOCDIFPHYADDR +void delifaddrs __P((char *, int)); +#endif #define NEXTARG 0xffffff @@ -113,6 +118,9 @@ struct cmd { } cmds[] = { { "up", IFF_UP, setifflags } , { "down", -IFF_UP, setifflags }, +#ifdef SIOCDIFPHYADDR + { "delete", 0, delifaddrs }, +#endif { 0, 0, setifpsrc }, { 0, 0, setifpdst }, }; @@ -151,7 +159,7 @@ struct afswtch { caddr_t af_addreq; caddr_t af_req; } afs[] = { -#define C(x) ((caddr_t) &x) +#define C(x) ((caddr_t) &x) { "inet", AF_INET, in_status, in_getaddr, 0, SIOCSIFPHYADDR, C(addreq), C(ifr) }, #ifdef INET6 @@ -174,9 +182,9 @@ int ifconfig __P((int argc, char *argv[], int af, struct afswtch *rafp)); * configuration read via sysctl(). */ -#define ROUNDUP(a) \ +#define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) void rt_xaddrs(cp, cplim, rtinfo) @@ -219,8 +227,14 @@ main(argc, argv) int all; if (argc < 2) { - fprintf(stderr, "usage: gifconfig interface %s", - "[ af ] physsrc physdst\n"); + fprintf(stderr, + "usage: gifconfig interface [af] [physsrc physdst]\n"); +#ifdef SIOCDIFPHYADDR + fprintf(stderr, + " gifconfig interface delete\n"); +#endif + fprintf(stderr, + " gifconfig -a\n"); exit(1); } argc--, argv++; @@ -335,7 +349,7 @@ main(argc, argv) if (all == 0) errx(1, "interface %s does not exist", name); - + exit (0); } @@ -395,15 +409,18 @@ ifconfig(argc, argv, af, rafp) } argc--, argv++; } - if (1 /*newaddr*/) { + if (newaddr) { strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name); if (ioctl(s, rafp->af_pifaddr, rafp->af_addreq) < 0) Perror("ioctl (SIOCSIFPHYADDR)"); } + else if (setpsrc) { + errx(1, "destination is not specified"); + } return(0); } -#define PSRC 0 -#define PDST 1 +#define PSRC 0 +#define PDST 1 /*ARGSUSED*/ void @@ -424,6 +441,7 @@ setifpdst(addr, param) { param = 0; /*fool gcc*/ (*afp->af_getaddr)(addr, PDST); + newaddr = 1; } void @@ -448,6 +466,21 @@ setifflags(vname, value) Perror(vname); } +#ifdef SIOCDIFPHYADDR +/* ARGSUSED */ +void +delifaddrs(vname, param) + char *vname; + int param; +{ + param = 0; /* fool gcc */ + vname = NULL; /* ditto */ + + if (ioctl(s, SIOCDIFPHYADDR, (caddr_t)&ifr) < 0) + err(1, "ioctl(SIOCDIFPHYADDR)"); +} +#endif + #define IFFBITS \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\ \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST" @@ -536,24 +569,35 @@ phys_status(force) int flags = NI_NUMERICHOST; struct ifreq *ifrp; char *ver = ""; +#ifdef INET6 + int s6; +#endif force = 0; /*fool gcc*/ psrcaddr[0] = pdstaddr[0] = '\0'; #ifdef INET6 - srccmd = SIOCGIFPSRCADDR_IN6; - dstcmd = SIOCGIFPDSTADDR_IN6; - ifrp = (struct ifreq *)&in6_ifr; + s6 = socket(AF_INET6, SOCK_DGRAM, 0); + if (s6 < 0) { + ifrp = 𝔦 + srccmd = SIOCGIFPSRCADDR; + dstcmd = SIOCGIFPDSTADDR; + } else { + close(s6); + srccmd = SIOCGIFPSRCADDR_IN6; + dstcmd = SIOCGIFPDSTADDR_IN6; + ifrp = (struct ifreq *)&in6_ifr; + } #else /* INET6 */ - ifrp = ifr; + ifrp = 𝔦 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); + hostname, sizeof(hostname), 0, 0, flags); #ifdef INET6 if (ifrp->ifr_addr.sa_family == AF_INET6) ver = "6"; @@ -562,7 +606,7 @@ phys_status(force) } if (0 <= ioctl(s, dstcmd, (caddr_t)ifrp)) { getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len, - hostname, NI_MAXHOST, 0, 0, flags); + hostname, sizeof(hostname), 0, 0, flags); sprintf(pdstaddr, "%s", hostname); } printf("\tphysical address %s --> %s\n", psrcaddr, pdstaddr); @@ -576,7 +620,7 @@ in_status(force) #if 0 char *inet_ntoa(); #endif - + memset(&null_sin, 0, sizeof(null_sin)); sin = (struct sockaddr_in *)info.rti_info[RTAX_IFA]; @@ -616,12 +660,13 @@ in6_status(force) int force; { struct sockaddr_in6 *sin, null_sin; -#if 0 - char *inet_ntop(); -#endif - + char hostname[NI_MAXHOST]; + int niflags = NI_NUMERICHOST; memset(&null_sin, 0, sizeof(null_sin)); +#ifdef NI_WITHSCOPEID + niflags |= NI_WITHSCOPEID; +#endif sin = (struct sockaddr_in6 *)info.rti_info[RTAX_IFA]; if (!sin || sin->sin6_family != AF_INET6) { @@ -630,8 +675,17 @@ in6_status(force) /* 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))); +#ifdef __KAME__ + if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { + sin->sin6_scope_id = + ntohs(*(u_int16_t *)&sin->sin6_addr.s6_addr[2]); + sin->sin6_addr.s6_addr[2] = 0; + sin->sin6_addr.s6_addr[3] = 0; + } +#endif + getnameinfo((struct sockaddr *)sin, sin->sin6_len, + hostname, sizeof(hostname), 0, 0, niflags); + printf("\tinet6 %s ", hostname); if (flags & IFF_POINTOPOINT) { /* note RTAX_BRD overlap with IFF_BROADCAST */ @@ -641,10 +695,17 @@ in6_status(force) * 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))); +#ifdef __KAME__ + if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { + sin->sin6_scope_id = + ntohs(*(u_int16_t *)&sin->sin6_addr.s6_addr[2]); + sin->sin6_addr.s6_addr[2] = 0; + sin->sin6_addr.s6_addr[3] = 0; + } +#endif + getnameinfo((struct sockaddr *)sin, sin->sin6_len, + hostname, sizeof(hostname), 0, 0, niflags); + printf("--> %s ", hostname); } } @@ -684,8 +745,6 @@ void Perror(cmd) char *cmd; { - extern int errno; - switch (errno) { case ENXIO: @@ -701,7 +760,7 @@ Perror(cmd) } } -#define SIN(x) ((struct sockaddr_in *) &(x)) +#define SIN(x) ((struct sockaddr_in *) &(x)) struct sockaddr_in *sintab[] = { SIN(addreq.ifra_addr), SIN(addreq.ifra_dstaddr)}; @@ -728,7 +787,7 @@ in_getaddr(s, which) } #ifdef INET6 -#define SIN6(x) ((struct sockaddr_in6 *) &(x)) +#define SIN6(x) ((struct sockaddr_in6 *) &(x)) struct sockaddr_in6 *sin6tab[] = { SIN6(in6_addreq.ifra_addr), SIN6(in6_addreq.ifra_dstaddr)}; diff --git a/usr.sbin/ifmcstat/ifmcstat.c b/usr.sbin/ifmcstat/ifmcstat.c index 9fe262f65623e..862601ae282ca 100644 --- a/usr.sbin/ifmcstat/ifmcstat.c +++ b/usr.sbin/ifmcstat/ifmcstat.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -44,12 +44,14 @@ #include <net/if_types.h> #include <net/if_dl.h> #include <netinet/in.h> -#define _KERNEL +#define _KERNEL #include <netinet/if_ether.h> -#undef _KERNEL +#undef _KERNEL #include <netinet/in_var.h> #include <arpa/inet.h> +#include <netdb.h> + kvm_t *kvmd; struct nlist nl[] = { @@ -64,19 +66,48 @@ char *ifname __P((struct ifnet *)); void kread __P((u_long, void *, int)); void if6_addrlist __P((struct ifaddr *)); void in6_multilist __P((struct in6_multi *)); -void in6_multientry __P((struct in6_multi *)); +struct in6_multi * in6_multientry __P((struct in6_multi *)); #define KREAD(addr, buf, type) \ kread((u_long)addr, (void *)buf, sizeof(type)) +#ifdef N_IN6_MK +struct multi6_kludge { + LIST_ENTRY(multi6_kludge) mk_entry; + struct ifnet *mk_ifp; + struct in6_multihead mk_head; +}; +#endif + const char *inet6_n2a(p) struct in6_addr *p; { - static char buf[BUFSIZ]; + static char buf[NI_MAXHOST]; + struct sockaddr_in6 sin6; + u_int32_t scopeid; +#ifdef NI_WITHSCOPEID + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; +#else + const int niflags = NI_NUMERICHOST; +#endif - if (IN6_IS_ADDR_UNSPECIFIED(p)) - return "*"; - return inet_ntop(AF_INET6, (void *)p, buf, sizeof(buf)); + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_addr = *p; + if (IN6_IS_ADDR_LINKLOCAL(p) || IN6_IS_ADDR_MC_LINKLOCAL(p)) { + scopeid = ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]); + if (scopeid) { + sin6.sin6_scope_id = scopeid; + sin6.sin6_addr.s6_addr[2] = 0; + sin6.sin6_addr.s6_addr[3] = 0; + } + } + if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, + buf, sizeof(buf), NULL, 0, niflags) == 0) + return buf; + else + return "(invalid)"; } int main() @@ -101,8 +132,13 @@ int main() while (ifp) { KREAD(ifp, &ifnet, struct ifnet); printf("%s:\n", if_indextoname(ifnet.if_index, ifname)); + if6_addrlist(TAILQ_FIRST(&ifnet.if_addrhead)); - ifp = TAILQ_NEXT(&ifnet, if_link); + nifp = ifnet.if_link.tqe_next; + + /* not supported */ + + ifp = nifp; } exit(0); @@ -113,8 +149,13 @@ char *ifname(ifp) struct ifnet *ifp; { static char buf[BUFSIZ]; + struct ifnet ifnet; + char ifnamebuf[IFNAMSIZ]; - KREAD(ifp->if_name, buf, IFNAMSIZ); + KREAD(ifp, &ifnet, struct ifnet); + KREAD(ifnet.if_name, ifnamebuf, sizeof(ifnamebuf)); + snprintf(buf, sizeof(buf), "%s%d", ifnamebuf, + ifnet.if_unit); /* does snprintf allow overlap copy?? */ return buf; } @@ -133,68 +174,97 @@ void if6_addrlist(ifap) struct ifaddr *ifap; { - static char in6buf[BUFSIZ]; - struct ifnet ifnet; struct ifaddr ifa; - struct ifaddr *ifap0; - struct ifmultiaddr ifm, *ifmp = 0; - struct in6_ifaddr if6a; - struct in6_multi *mc = 0, in6m; - int in6_multilist_done = 0; struct sockaddr sa; - struct sockaddr_in6 sin6; - struct sockaddr_dl sdl; + struct in6_ifaddr if6a; + struct in6_multi *mc = 0; + struct ifaddr *ifap0; - if (ifap == NULL) - return; ifap0 = ifap; - - do { + while (ifap) { KREAD(ifap, &ifa, struct ifaddr); if (ifa.ifa_addr == NULL) - continue; + goto nextifap; KREAD(ifa.ifa_addr, &sa, struct sockaddr); if (sa.sa_family != PF_INET6) - continue; + 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))); - } while ((ifap = TAILQ_NEXT(&ifa, ifa_link)) != NULL); + printf("\tinet6 %s\n", inet6_n2a(&if6a.ia_addr.sin6_addr)); + nextifap: + ifap = ifa.ifa_link.tqe_next; + } + 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; + } + } +#ifdef N_IN6_MK + if (nl[N_IN6_MK].n_value != 0) { + LIST_HEAD(in6_mktype, multi6_kludge) in6_mk; + struct multi6_kludge *mkp, mk; + char *nam; + + KREAD(nl[N_IN6_MK].n_value, &in6_mk, struct in6_mktype); + KREAD(ifap0, &ifa, struct ifaddr); + + nam = strdup(ifname(ifa.ifa_ifp)); - KREAD(ifap0, &ifa, struct ifaddr); - KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); - if (ifnet.if_multiaddrs.lh_first) - ifmp = ifnet.if_multiaddrs.lh_first; - if (ifmp == NULL) - return; - do { - KREAD(ifmp, &ifm, struct ifmultiaddr); - if (ifm.ifma_addr == NULL) - continue; - KREAD(ifm.ifma_addr, &sa, struct sockaddr); - if (sa.sa_family != AF_INET6) - continue; - in6_multientry((struct in6_multi *)ifm.ifma_protospec); - if (ifm.ifma_lladdr == 0) - continue; - 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); - } while ((ifmp = LIST_NEXT(&ifm, ifma_link)) != NULL); + for (mkp = in6_mk.lh_first; mkp; mkp = mk.mk_entry.le_next) { + KREAD(mkp, &mk, struct multi6_kludge); + if (strcmp(nam, ifname(mk.mk_ifp)) == 0 && + mk.mk_head.lh_first) { + printf("\t(on kludge entry for %s)\n", nam); + in6_multilist(mk.mk_head.lh_first); + } + } + + free(nam); + } +#endif } -void +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))); + printf("\t\tgroup %s", inet6_n2a(&multi.in6m_addr)); + printf(" refcnt %u\n", multi.in6m_refcount); + return(multi.in6m_entry.le_next); +} + +void +in6_multilist(mc) + struct in6_multi *mc; +{ + while (mc) + mc = in6_multientry(mc); } diff --git a/usr.sbin/mld6query/Makefile b/usr.sbin/mld6query/Makefile index c1cdd8fee4770..87f9fbf8fa471 100644 --- a/usr.sbin/mld6query/Makefile +++ b/usr.sbin/mld6query/Makefile @@ -11,6 +11,8 @@ # AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT # LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE. +# +# $FreeBSD$ PROG= mld6query SRCS= mld6.c diff --git a/usr.sbin/mld6query/mld6.c b/usr.sbin/mld6query/mld6.c index 473e0f4f00fc8..c485c86f30cfc 100644 --- a/usr.sbin/mld6query/mld6.c +++ b/usr.sbin/mld6query/mld6.c @@ -25,6 +25,8 @@ * 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/uio.h> diff --git a/usr.sbin/mld6query/mld6query.8 b/usr.sbin/mld6query/mld6query.8 index 470e18ae63f7e..2df9d78369a53 100644 --- a/usr.sbin/mld6query/mld6query.8 +++ b/usr.sbin/mld6query/mld6query.8 @@ -26,6 +26,7 @@ .\" SUCH DAMAGE. .\" .\" $Id: mld6query.8,v 1.3 1999/08/20 10:00:06 itojun Exp $ +.\" $FreeBSD$ .\" .Dd May 17, 1998 .Dt MLD6QUERY 8 diff --git a/usr.sbin/ndp/ndp.8 b/usr.sbin/ndp/ndp.8 index f845d5e79d2c2..fc99d3696eed5 100644 --- a/usr.sbin/ndp/ndp.8 +++ b/usr.sbin/ndp/ndp.8 @@ -1,3 +1,6 @@ +.\" $FreeBSD$ +.\" $KAME: ndp.8,v 1.12 2000/06/20 21:50:17 itojun Exp $ +.\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. .\" @@ -25,9 +28,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: ndp.8,v 1.2 1999/10/07 05:26:13 itojun Exp $ -.\" $FreeBSD$ -.\" .Dd May 17, 1998 .Dt NDP 8 .Os KAME @@ -57,8 +57,12 @@ .Nm ndp .Fl H .Nm ndp +.Fl I +.Op delete \(ba Ar interface +.Nm ndp .Fl i .Ar interface +.Op Ar flags... .Nm ndp .Fl p .Nm ndp @@ -72,7 +76,8 @@ .Op Fl nt .Ar nodename .Ar ether_addr -.Op temp +.Op Li temp +.Op Li proxy .\" .Sh DESCRIPTION The @@ -99,8 +104,35 @@ Parse the file specified by .It Fl H Harmonize consistency between the routing table and the default router list; install the top entry of the list into the kernel routing table. -.It Fl i -view ND information for specified interface. +.It Fl I Op delete \(ba Ar interface +Shows or specifies the default interface used as the default route when +there is no default router. If no argument is given to the option, +the current default interface will be shown. +If an +.Ar interface +is specified, the interface will be used as the default. +If a special keyword +.Ic delete +is specified, the current default interface will be deleted from the kernel. +.It Fl i Ar interface Op Ar flags... +View ND information for the specified interface. +If additional arguments +.Ar flags +are given, +.Nm +sets or clears the specified flags for the interface. +Possible flags are as follows. All of the flags can begin with the +special character +.Ql - , +which means the flag should be cleared. +.\" +.Bl -tag -width Ds -compact +.It Xo +.Ic nud +.Xc +turn on or off NUD (Neighbor Unreachability Detection) on the +interface. NUD is usually turned on by default. +.El .It Fl l Do not truncate numeric IPv6 address. .It Fl n @@ -115,6 +147,15 @@ Show default router list. Flush all the entries in the default router list. .It Fl s Register a NDP entry for a node. +The entry will be permanent unless the word +.Li temp +is given in the command. +If the word +.Li proxy +is given, this system will act as an proxy NDP server, +responding to requests for +.Ar hostname +even though the host address is not its own. .It Fl t Print timestamp on each entries, to make it possible to merge output with diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index 54568a404c0cc..8010c1906354d 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -1,3 +1,6 @@ +/* $FreeBSD$ */ +/* $KAME: ndp.c,v 1.41 2000/07/04 12:54:11 jinmei Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. @@ -25,8 +28,6 @@ * 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$ */ /* * Copyright (c) 1984, 1993 @@ -111,47 +112,55 @@ #include <unistd.h> #include "gmt2local.h" +#ifndef NI_WITHSCOPEID +#define NI_WITHSCOPEID 0 +#endif + /* packing rule for routing socket */ -#define ROUNDUP(a) \ +#define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) -extern int errno; -static int pid; -static int fflag; -static int nflag; -static int tflag; -static int32_t thiszone; /* time difference with gmt */ -static int s = -1; -static int repeat = 0; -static int lflag = 0; +static int pid; +static int fflag; +static int nflag; +static int tflag; +static int32_t thiszone; /* time difference with gmt */ +static int s = -1; +static int repeat = 0; +static int lflag = 0; -char ntop_buf[INET6_ADDRSTRLEN]; /* inet_ntop() */ -char host_buf[NI_MAXHOST]; /* getnameinfo() */ -char ifix_buf[IFNAMSIZ]; /* if_indextoname() */ +char ntop_buf[INET6_ADDRSTRLEN]; /* inet_ntop() */ +char host_buf[NI_MAXHOST]; /* getnameinfo() */ +char ifix_buf[IFNAMSIZ]; /* if_indextoname() */ -int main __P((int, char **)); -int file __P((char *)); -void getsocket __P((void)); -int set __P((int, char **)); -void get __P((char *)); -int delete __P((char *)); -void dump __P((struct in6_addr *)); -static struct in6_nbrinfo *getnbrinfo __P((struct in6_addr *addr, int ifindex)); -static char *ether_str __P((struct sockaddr_dl *)); -int ndp_ether_aton __P((char *, u_char *)); -void usage __P((void)); -int rtmsg __P((int)); -void ifinfo __P((char *)); -void list __P((void)); -void plist __P((void)); -void pfx_flush __P((void)); -void rtrlist __P((void)); -void rtr_flush __P((void)); -void harmonize_rtr __P((void)); -static char *sec2str __P((time_t t)); -static char *ether_str __P((struct sockaddr_dl *sdl)); -static void ts_print __P((const struct timeval *)); +int main __P((int, char **)); +int file __P((char *)); +void getsocket __P((void)); +int set __P((int, char **)); +void get __P((char *)); +int delete __P((char *)); +void dump __P((struct in6_addr *)); +static struct in6_nbrinfo *getnbrinfo __P((struct in6_addr *addr, + int ifindex, int)); +static char *ether_str __P((struct sockaddr_dl *)); +int ndp_ether_aton __P((char *, u_char *)); +void usage __P((void)); +int rtmsg __P((int)); +void ifinfo __P((int, char **)); +void rtrlist __P((void)); +void plist __P((void)); +void pfx_flush __P((void)); +void rtrlist __P((void)); +void rtr_flush __P((void)); +void harmonize_rtr __P((void)); +#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ +static void getdefif __P((void)); +static void setdefif __P((char *)); +#endif +static char *sec2str __P((time_t t)); +static char *ether_str __P((struct sockaddr_dl *sdl)); +static void ts_print __P((const struct timeval *)); int main(argc, argv) @@ -161,12 +170,10 @@ main(argc, argv) int ch; int aflag = 0, cflag = 0, dflag = 0, sflag = 0, Hflag = 0, pflag = 0, rflag = 0, Pflag = 0, Rflag = 0; - extern char *optarg; - extern int optind; pid = getpid(); thiszone = gmt2local(0); - while ((ch = getopt(argc, argv, "acndfilprstA:HPR")) != EOF) + while ((ch = getopt(argc, argv, "acndfIilprstA:HPR")) != EOF) switch ((char)ch) { case 'a': aflag = 1; @@ -178,10 +185,22 @@ main(argc, argv) case 'd': dflag = 1; break; + case 'I': +#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ + if (argc > 2) + setdefif(argv[2]); + getdefif(); /* always call it to print the result */ + exit(0); +#else + errx(1, "not supported yet"); + /*NOTREACHED*/ +#endif case 'i' : - if (argc != 3) + argc -= optind; + argv += optind; + if (argc < 1) usage(); - ifinfo(argv[2]); + ifinfo(argc, argv); exit(0); case 'n': nflag = 1; @@ -236,6 +255,7 @@ main(argc, argv) if (argc != 1) usage(); delete(argv[0]); + exit(0); } if (pflag) { plist(); @@ -317,7 +337,7 @@ getsocket() } } -struct sockaddr_in so_mask = {8, 0, 0, { 0xffffffff}}; +struct sockaddr_in6 so_mask = {sizeof(so_mask), AF_INET6 }; struct sockaddr_in6 blank_sin = {sizeof(blank_sin), AF_INET6 }, sin_m; struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m; int expire_time, flags, found_entry; @@ -357,6 +377,12 @@ set(argc, argv) return 1; } sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; +#ifdef __KAME__ + if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { + *(u_int16_t *)&sin->sin6_addr.s6_addr[2] = + htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); + } +#endif ea = (u_char *)LLADDR(&sdl_m); if (ndp_ether_aton(eaddr, ea) == 0) sdl_m.sdl_alen = 6; @@ -366,10 +392,10 @@ set(argc, argv) struct timeval time; gettimeofday(&time, 0); expire_time = time.tv_sec + 20 * 60; - } + } else if (strncmp(argv[0], "proxy", 5) == 0) + flags |= RTF_ANNOUNCE; argv++; } -tryagain: if (rtmsg(RTM_GET) < 0) { perror(host); return (1); @@ -384,8 +410,13 @@ tryagain: case IFT_ISO88024: case IFT_ISO88025: goto overwrite; } - goto tryagain; + /* + * IPv4 arp command retries with sin_other = SIN_PROXY here. + */ + fprintf(stderr, "set: cannot configure a new entry\n"); + return 1; } + overwrite: if (sdl->sdl_family != AF_LINK) { printf("cannot intuit interface index and type for %s\n", host); @@ -417,6 +448,12 @@ get(host) return; } sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; +#ifdef __KAME__ + if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { + *(u_int16_t *)&sin->sin6_addr.s6_addr[2] = + htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); + } +#endif dump(&sin->sin6_addr); if (found_entry == 0) { getnameinfo((struct sockaddr *)sin, sin->sin6_len, host_buf, @@ -452,7 +489,12 @@ delete(host) return 1; } sin->sin6_addr = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; -/*tryagain:*/ +#ifdef __KAME__ + if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) { + *(u_int16_t *)&sin->sin6_addr.s6_addr[2] = + htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id); + } +#endif if (rtmsg(RTM_GET) < 0) { perror(host); return (1); @@ -462,23 +504,38 @@ delete(host) if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) { if (sdl->sdl_family == AF_LINK && (rtm->rtm_flags & RTF_LLINFO) && - !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { - case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: - case IFT_ISO88024: case IFT_ISO88025: - goto delete; + !(rtm->rtm_flags & RTF_GATEWAY)) { + switch (sdl->sdl_type) { + case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: + case IFT_ISO88024: case IFT_ISO88025: + goto delete; + } } + /* + * IPv4 arp command retries with sin_other = SIN_PROXY here. + */ + fprintf(stderr, "delete: cannot delete non-NDP entry\n"); + return 1; } - return 0; + delete: if (sdl->sdl_family != AF_LINK) { printf("cannot locate %s\n", host); return (1); } if (rtmsg(RTM_DELETE) == 0) { - getnameinfo((struct sockaddr *)sin, - sin->sin6_len, host_buf, - sizeof(host_buf), NULL, 0, - NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); + struct sockaddr_in6 s6 = *sin; /* XXX: for safety */ + +#ifdef __KAME__ + if (IN6_IS_ADDR_LINKLOCAL(&s6.sin6_addr)) { + s6.sin6_scope_id = ntohs(*(u_int16_t *)&s6.sin6_addr.s6_addr[2]); + *(u_int16_t *)&s6.sin6_addr.s6_addr[2] = 0; + } +#endif + getnameinfo((struct sockaddr *)&s6, + s6.sin6_len, host_buf, + sizeof(host_buf), NULL, 0, + NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); printf("%s (%s) deleted\n", host, host_buf); } @@ -494,19 +551,19 @@ dump(addr) { int mib[6]; size_t needed; - char *host, *lim, *buf, *next; + char *lim, *buf, *next; struct rt_msghdr *rtm; struct sockaddr_in6 *sin; struct sockaddr_dl *sdl; extern int h_errno; - struct hostent *hp; struct in6_nbrinfo *nbi; struct timeval time; int addrwidth; + char flgbuf[8]; /* Print header */ if (!tflag) - printf("%-29.29s %-18.18s %6.6s %-9.9s %2s %4s %4s\n", + printf("%-31.31s %-17.17s %6.6s %-9.9s %2s %4s %4s\n", "Neighbor", "Linklayer Address", "Netif", "Expire", "St", "Flgs", "Prbs"); @@ -564,18 +621,17 @@ again:; if (lflag) { addrwidth = strlen(host_buf); - if (addrwidth < 29) - addrwidth = 29; + if (addrwidth < 31) + addrwidth = 31; } else - addrwidth = 29; + addrwidth = 31; - printf("%-*.*s %-18.18s %6.6s", addrwidth, addrwidth, host_buf, + printf("%-*.*s %-17.17s %6.6s", addrwidth, addrwidth, host_buf, ether_str(sdl), if_indextoname(sdl->sdl_index, ifix_buf)); /* Print neighbor discovery specific informations */ - putchar(' '); - nbi = getnbrinfo(&sin->sin6_addr, sdl->sdl_index); + nbi = getnbrinfo(&sin->sin6_addr, sdl->sdl_index, 1); if (nbi) { if (nbi->expire > time.tv_sec) { printf(" %-9.9s", @@ -620,31 +676,30 @@ again:; warnx("failed to get neighbor information"); printf(" "); } - - /* other flags */ putchar(' '); - { - u_char flgbuf[8], *p = flgbuf; - flgbuf[0] = '\0'; - if (isrouter) - p += sprintf((char *)p, "R"); -#ifndef RADISH - if (rtm->rtm_addrs & RTA_NETMASK) { - sin = (struct sockaddr_in6 *) - (sdl->sdl_len + (char *)sdl); - if (!IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr)) - p += sprintf((char *)p, "P"); - if (sin->sin6_len != sizeof(struct sockaddr_in6)) - p += sprintf((char *)p, "W"); - } -#endif /*RADISH*/ - printf("%4s", flgbuf); + /* + * other flags. R: router, P: proxy, W: ?? + */ + if ((rtm->rtm_addrs & RTA_NETMASK) == 0) { + snprintf(flgbuf, sizeof(flgbuf), "%s%s", + isrouter ? "R" : "", + (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); + } else { + sin = (struct sockaddr_in6 *) + (sdl->sdl_len + (char *)sdl); + snprintf(flgbuf, sizeof(flgbuf), "%s%s%s%s", + isrouter ? "R" : "", + !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr) + ? "P" : "", + (sin->sin6_len != sizeof(struct sockaddr_in6)) + ? "W" : "", + (rtm->rtm_flags & RTF_ANNOUNCE) ? "p" : ""); } + printf(" %-4.4s", flgbuf); - putchar(' '); if (prbs) - printf("% 4d", prbs); + printf(" %4d", prbs); printf("\n"); } @@ -657,9 +712,10 @@ again:; } static struct in6_nbrinfo * -getnbrinfo(addr, ifindex) +getnbrinfo(addr, ifindex, warning) struct in6_addr *addr; int ifindex; + int warning; { static struct in6_nbrinfo nbi; int s; @@ -671,7 +727,8 @@ getnbrinfo(addr, ifindex) if_indextoname(ifindex, nbi.ifname); nbi.addr = *addr; if (ioctl(s, SIOCGNBRINFO_IN6, (caddr_t)&nbi) < 0) { - warn("ioctl"); + if (warning) + warn("ioctl(SIOCGNBRINFO_IN6)"); close(s); return(NULL); } @@ -726,10 +783,13 @@ usage() printf(" ndp -c[nt]\n"); printf(" ndp -d[nt] hostname\n"); printf(" ndp -f[nt] filename\n"); - printf(" ndp -i interface\n"); + printf(" ndp -i interface [flags...]\n"); +#ifdef SIOCSDEFIFACE_IN6 + printf(" ndp -I [interface|delete]\n"); +#endif printf(" ndp -p\n"); printf(" ndp -r\n"); - printf(" ndp -s hostname ether_addr [temp]\n"); + printf(" ndp -s hostname ether_addr [temp] [proxy]\n"); printf(" ndp -H\n"); printf(" ndp -P\n"); printf(" ndp -R\n"); @@ -762,16 +822,21 @@ rtmsg(cmd) rtm->rtm_rmx.rmx_expire = expire_time; rtm->rtm_inits = RTV_EXPIRE; rtm->rtm_flags |= (RTF_HOST | RTF_STATIC); + if (rtm->rtm_flags & RTF_ANNOUNCE) { + rtm->rtm_flags &= ~RTF_HOST; + rtm->rtm_flags |= RTA_NETMASK; + } /* FALLTHROUGH */ case RTM_GET: rtm->rtm_addrs |= RTA_DST; } -#define NEXTADDR(w, s) \ +#define NEXTADDR(w, s) \ if (rtm->rtm_addrs & (w)) { \ bcopy((char *)&s, cp, sizeof(s)); cp += sizeof(s);} NEXTADDR(RTA_DST, sin_m); NEXTADDR(RTA_GATEWAY, sdl_m); + memset(&so_mask.sin6_addr, 0xff, sizeof(so_mask.sin6_addr)); NEXTADDR(RTA_NETMASK, so_mask); rtm->rtm_msglen = cp - (char *)&m_rtmsg; @@ -795,11 +860,14 @@ doit: } void -ifinfo(ifname) - char *ifname; +ifinfo(argc, argv) + int argc; + char **argv; { struct in6_ndireq nd; - int s; + int i, s; + char *ifname = argv[0]; + u_int32_t newflags; if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { perror("ndp: socket"); @@ -811,14 +879,50 @@ ifinfo(ifname) perror("ioctl (SIOCGIFINFO_IN6)"); exit(1); } -#define ND nd.ndi +#define ND nd.ndi + newflags = ND.flags; + for (i = 1; i < argc; i++) { + int clear = 0; + char *cp = argv[i]; + + if (*cp == '-') { + clear = 1; + cp++; + } + +#define SETFLAG(s, f) \ + do {\ + if (strcmp(cp, (s)) == 0) {\ + if (clear)\ + newflags &= ~(f);\ + else\ + newflags |= (f);\ + }\ + } while (0) + SETFLAG("nud", ND6_IFF_PERFORMNUD); + + ND.flags = newflags; + if (ioctl(s, SIOCSIFINFO_FLAGS, (caddr_t)&nd) < 0) { + perror("ioctl(SIOCSIFINFO_FLAGS)"); + exit(1); + } +#undef SETFLAG + } + printf("linkmtu=%d", ND.linkmtu); printf(", curhlim=%d", ND.chlim); printf(", basereachable=%ds%dms", ND.basereachable / 1000, ND.basereachable % 1000); printf(", reachable=%ds", ND.reachable); - printf(", retrans=%ds%dms\n", ND.retrans / 1000, ND.retrans % 1000); + printf(", retrans=%ds%dms", ND.retrans / 1000, ND.retrans % 1000); + if (ND.flags) { + printf("\nFlags: "); + if ((ND.flags & ND6_IFF_PERFORMNUD) != 0) + printf("PERFORMNUD "); + } + putc('\n', stdout); #undef ND + close(s); } @@ -839,7 +943,7 @@ rtrlist() perror("ioctl (SIOCGDRLST_IN6)"); exit(1); } -#define DR dr.defrouter[i] +#define DR dr.defrouter[i] for (i = 0 ; DR.if_index && i < PRLSTSIZ ; i++) { struct sockaddr_in6 sin6; @@ -850,7 +954,7 @@ rtrlist() getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, host_buf, sizeof(host_buf), NULL, 0, NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); - + printf("%s if=%s", host_buf, if_indextoname(DR.if_index, ifix_buf)); printf(", flags=%s%s", @@ -886,14 +990,19 @@ plist() perror("ioctl (SIOCGPRLST_IN6)"); exit(1); } -#define PR pr.prefix[i] +#define PR pr.prefix[i] for (i = 0; PR.if_index && i < PRLSTSIZ ; i++) { printf("%s/%d if=%s\n", inet_ntop(AF_INET6, &PR.prefix, ntop_buf, sizeof(ntop_buf)), PR.prefixlen, if_indextoname(PR.if_index, ifix_buf)); gettimeofday(&time, 0); - printf(" flags=%s%s", + /* + * meaning of fields, especially flags, is very different + * by origin. notify the difference to the users. + */ + printf(" %s", PR.origin == PR_ORIG_RA ? "" : "advertise: "); + printf("flags=%s%s", PR.raflags.onlink ? "L" : "", PR.raflags.autonomous ? "A" : ""); if (PR.vltime == ND6_INFINITE_LIFETIME) @@ -905,34 +1014,75 @@ plist() else printf(", pltime=%ld", (long)PR.pltime); if (PR.expire == 0) - printf(", expire=Never\n"); + printf(", expire=Never"); else if (PR.expire >= time.tv_sec) - printf(", expire=%s\n", + printf(", expire=%s", sec2str(PR.expire - time.tv_sec)); else - printf(", expired\n"); - if (PR.advrtrs) { + printf(", expired"); + switch (PR.origin) { + case PR_ORIG_RA: + printf(", origin=RA"); + break; + case PR_ORIG_RR: + printf(", origin=RR"); + break; + case PR_ORIG_STATIC: + printf(", origin=static"); + break; + case PR_ORIG_KERNEL: + printf(", origin=kernel"); + break; + default: + printf(", origin=?"); + break; + } + printf("\n"); + /* + * "advertising router" list is meaningful only if the prefix + * information is from RA. + */ + if (PR.origin != PR_ORIG_RA) + ; + else if (PR.advrtrs) { int j; printf(" advertised by\n"); for (j = 0; j < PR.advrtrs; j++) { struct sockaddr_in6 sin6; + struct in6_nbrinfo *nbi; bzero(&sin6, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_len = sizeof(sin6); sin6.sin6_addr = PR.advrtr[j]; + sin6.sin6_scope_id = PR.if_index; /* XXX */ getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, host_buf, sizeof(host_buf), NULL, 0, NI_WITHSCOPEID | (nflag ? NI_NUMERICHOST : 0)); + printf(" %s", host_buf); - printf(" %s\n", host_buf); + nbi = getnbrinfo(&sin6.sin6_addr, PR.if_index, + 0); + if (nbi) { + switch(nbi->state) { + case ND6_LLINFO_REACHABLE: + case ND6_LLINFO_STALE: + case ND6_LLINFO_DELAY: + case ND6_LLINFO_PROBE: + printf(" (reachable)\n"); + break; + default: + printf(" (unreachable)\n"); + } + } + else + printf(" (no neighbor state)\n"); } if (PR.advrtrs > DRLSTSIZ) printf(" and %d routers\n", PR.advrtrs - DRLSTSIZ); - } - else + } else printf(" No advertising router\n"); } #undef PR @@ -963,6 +1113,8 @@ rtr_flush() strcpy(dummyif, "lo0"); /* dummy */ if (ioctl(s, SIOCSRTRFLUSH_IN6, (caddr_t)&dummyif) < 0) err(1, "ioctl(SIOCSRTRFLUSH_IN6)"); + + close(s); } void @@ -971,16 +1123,69 @@ harmonize_rtr() char dummyif[IFNAMSIZ+8]; int s; - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - perror("ndp: socket"); - exit(1); - } + if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + err(1, "socket"); strcpy(dummyif, "lo0"); /* dummy */ - if (ioctl(s, SIOCSNDFLUSH_IN6, (caddr_t)&dummyif) < 0) { - perror("ioctl (SIOCSNDFLUSH_IN6)"); - exit(1); - } + if (ioctl(s, SIOCSNDFLUSH_IN6, (caddr_t)&dummyif) < 0) + err(1, "ioctl (SIOCSNDFLUSH_IN6)"); + + close(s); +} + +#ifdef SIOCSDEFIFACE_IN6 /* XXX: check SIOCGDEFIFACE_IN6 as well? */ +static void +setdefif(ifname) + char *ifname; +{ + struct in6_ndifreq ndifreq; + unsigned int ifindex; + + if (strcasecmp(ifname, "delete") == 0) + ifindex = 0; + else { + if ((ifindex = if_nametoindex(ifname)) == 0) + err(1, "failed to resolve i/f index for %s", ifname); + } + + if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + err(1, "socket"); + + strcpy(ndifreq.ifname, "lo0"); /* dummy */ + ndifreq.ifindex = ifindex; + + if (ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) + err(1, "ioctl (SIOCSDEFIFACE_IN6)"); + + close(s); +} + +static void +getdefif() +{ + struct in6_ndifreq ndifreq; + char ifname[IFNAMSIZ+8]; + + if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + err(1, "socket"); + + memset(&ndifreq, 0, sizeof(ndifreq)); + strcpy(ndifreq.ifname, "lo0"); /* dummy */ + + if (ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq) < 0) + err(1, "ioctl (SIOCGDEFIFACE_IN6)"); + + if (ndifreq.ifindex == 0) + printf("No default interface.\n"); + else { + if ((if_indextoname(ndifreq.ifindex, ifname)) == NULL) + err(1, "failed to resolve ifname for index %lu", + ndifreq.ifindex); + printf("ND default interface = %s\n", ifname); + } + + close(s); } +#endif static char * sec2str(total) diff --git a/usr.sbin/pim6dd/LICENSE.pimd b/usr.sbin/pim6dd/LICENSE.pimd index 384ad23b9689b..d88a4578bd1a4 100644 --- a/usr.sbin/pim6dd/LICENSE.pimd +++ b/usr.sbin/pim6dd/LICENSE.pimd @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,7 +31,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: LICENSE.pimd,v 1.1.1.1 1999/08/08 23:30:50 itojun Exp $ diff --git a/usr.sbin/pim6dd/Makefile b/usr.sbin/pim6dd/Makefile index b0fdcd344ce62..a35c7108af401 100644 --- a/usr.sbin/pim6dd/Makefile +++ b/usr.sbin/pim6dd/Makefile @@ -1,14 +1,90 @@ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 -# $FreeBSD$ +# 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. -PROG= pim6dd -MAN5= pim6dd.conf.5 -MAN8= pim6dd.8 +# Copyright (c) 1998 by the University of Oregon. +# All rights reserved. +# +# Permission to use, copy, modify, and distribute this software and +# its documentation in source and binary forms for lawful +# purposes and without fee is hereby granted, provided +# that the above copyright notice appear in all copies and that both +# the copyright notice and this permission notice appear in supporting +# documentation, and that any documentation, advertising materials, +# and other materials related to such distribution and use acknowledge +# that the software was developed by the University of Oregon. +# The name of the University of Oregon may not be used to endorse or +# promote products derived from this software without specific prior +# written permission. +# +# THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS +# ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND +# NON-INFRINGEMENT. +# +# IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY +# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, +# TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, +# THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# Other copyrights might apply to parts of this software and are so +# noted when applicable. +# +# +# Questions concerning this software should be directed to +# Kurt Windisch (kurtw@antc.uoregon.edu) +# +# $Id: Makefile,v 1.2 2000/02/25 06:32:22 itojun Exp $ +# +# +#Part of this program has been derived from PIM sparse-mode pimd. +#The pimd program is covered by the license in the accompanying file +#named "LICENSE.pimd". +# +#The pimd program is COPYRIGHT 1998 by University of Southern California. +# +#Part of this program has been derived from mrouted. +#The mrouted program is covered by the license in the accompanying file +#named "LICENSE.mrouted". +# +#The mrouted program is COPYRIGHT 1989 by The Board of Trustees of +#Leland Stanford Junior University. +# +# $FreeBSD$ +PROG= pim6dd SRCS= mld6.c mld6_proto.c\ inet6.c kern.c main.c config.c debug.c routesock.c vers.c callout.c\ route.c vif.c timer.c mrt.c pim6.c pim6_proto.c trace.c -CFLAGS+= -DINET6 -DPIM -DIOCTL_OK_ON_RAW_SOCKET +CFLAGS+=-Wall +CFLAGS+=-DINET6 -DPIM -DIOCTL_OK_ON_RAW_SOCKET -DHAVE_GETIFADDRS + +MAN5= pim6dd.conf.5 +MAN8= pim6dd.8 .include <bsd.prog.mk> diff --git a/usr.sbin/pim6dd/callout.c b/usr.sbin/pim6dd/callout.c index 6820dcd8b8d64..6cf96de052418 100644 --- a/usr.sbin/pim6dd/callout.c +++ b/usr.sbin/pim6dd/callout.c @@ -20,7 +20,7 @@ static struct timeout_q *Q = 0; /* pointer to the beginning of timeout queue */ struct timeout_q { struct timeout_q *next; /* next event */ - int id; + int id; cfunc_t func; /* function to call */ void *data; /* func's data */ int time; /* time offset to next event*/ @@ -29,7 +29,7 @@ struct timeout_q { #ifdef CALLOUT_DEBUG static void print_Q __P((void)); #else -#define print_Q() +#define print_Q() #endif void @@ -46,7 +46,7 @@ void free_all_callouts() { struct timeout_q *p; - + while (Q) { p = Q; Q = Q->next; @@ -64,7 +64,7 @@ age_callout_queue(elapsed_time) int elapsed_time; { struct timeout_q *ptr, *expQ; - + #ifdef CALLOUT_DEBUG IF_DEBUG(DEBUG_TIMEOUT) log(LOG_DEBUG, 0, "aging queue (elapsed time %d):", elapsed_time); @@ -73,7 +73,7 @@ age_callout_queue(elapsed_time) expQ = Q; ptr = NULL; - + while (Q) { if (Q->time > elapsed_time) { Q->time -= elapsed_time; @@ -88,7 +88,7 @@ age_callout_queue(elapsed_time) Q = Q->next; } } - + /* handle queue of expired timers */ while (expQ) { ptr = expQ; @@ -108,7 +108,7 @@ timer_nextTimer() { if (Q) { if (Q->time < 0) { - log(LOG_WARNING, 0, "timer_nextTimer top of queue says %d", + log(LOG_WARNING, 0, "timer_nextTimer top of queue says %d", Q->time); return 0; } @@ -117,7 +117,7 @@ timer_nextTimer() return -1; } -/* +/* * sets the timer */ int @@ -127,39 +127,39 @@ timer_setTimer(delay, action, data) void *data; /* what to call the timeout function with */ { struct timeout_q *ptr, *node, *prev; - + #ifdef CALLOUT_DEBUG IF_DEBUG(DEBUG_TIMEOUT) log(LOG_DEBUG, 0, "setting timer:"); print_Q(); #endif - /* create a node */ + /* create a node */ node = (struct timeout_q *)malloc(sizeof(struct timeout_q)); if (node == 0) { log(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n"); return -1; } - node->func = action; + node->func = action; node->data = data; - node->time = delay; - node->next = 0; + node->time = delay; + node->next = 0; node->id = ++id; - + prev = ptr = Q; - + /* insert node in the queue */ - + /* if the queue is empty, insert the node and return */ if (!Q) Q = node; else { /* chase the pointer looking for the right place */ while (ptr) { - + if (delay < ptr->time) { /* right place */ - + node->next = ptr; if (ptr == Q) Q = node; @@ -169,7 +169,7 @@ timer_setTimer(delay, action, data) return node->id; } else { /* keep moving */ - + delay -= ptr->time; node->time = delay; prev = ptr; ptr = ptr->next; @@ -187,10 +187,10 @@ timer_leftTimer(timer_id) { struct timeout_q *ptr; int left = 0; - + if (!timer_id) return -1; - + for (ptr = Q; ptr; ptr = ptr->next) { left += ptr->time; if (ptr->id == timer_id) @@ -205,31 +205,31 @@ timer_clearTimer(timer_id) int timer_id; { struct timeout_q *ptr, *prev; - + if (!timer_id) return; - + prev = ptr = Q; - + /* * find the right node, delete it. the subsequent node's time * gets bumped up */ - + while (ptr) { if (ptr->id == timer_id) { /* got the right node */ - + /* unlink it from the queue */ if (ptr == Q) Q = Q->next; else prev->next = ptr->next; - + /* increment next node if any */ if (ptr->next != 0) (ptr->next)->time += ptr->time; - + if (ptr->data) free(ptr->data); free(ptr); @@ -248,7 +248,7 @@ static void print_Q() { struct timeout_q *ptr; - + IF_DEBUG(DEBUG_TIMEOUT) for (ptr = Q; ptr; ptr = ptr->next) log(LOG_DEBUG, 0, "(%d,%d) ", ptr->id, ptr->time); diff --git a/usr.sbin/pim6dd/config.c b/usr.sbin/pim6dd/config.c index c52e06f16191e..f241287c430c2 100644 --- a/usr.sbin/pim6dd/config.c +++ b/usr.sbin/pim6dd/config.c @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,10 +31,10 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * - * $Id: config.c,v 1.3 1999/12/30 09:23:08 itojun Exp $ + * $Id: config.c,v 1.6 2000/02/23 16:10:26 itojun Exp $ */ /* * Part of this program has been derived from mrouted. @@ -48,6 +48,9 @@ */ #include "defs.h" +#ifdef HAVE_GETIFADDRS +#include <ifaddrs.h> +#endif /* @@ -69,21 +72,141 @@ static int parse_default_source_preference __P((char *)); * Query the kernel to find network interfaces that are multicast-capable * and install them in the uvifs array. */ -void +void config_vifs_from_kernel() { - struct ifreq *ifrp, *ifend; register struct uvif *v; register vifi_t vifi; - int n; struct sockaddr_in6 addr; struct in6_addr mask, prefix; short flags; +#ifdef HAVE_GETIFADDRS + struct ifaddrs *ifap, *ifa; +#else + int n; int num_ifreq = 64; struct ifconf ifc; + struct ifreq *ifrp, *ifend; +#endif total_interfaces = 0; /* The total number of physical interfaces */ + +#ifdef HAVE_GETIFADDRS + if (getifaddrs(&ifap)) + log(LOG_ERR, errno, "getiaddrs"); + + /* + * Loop through all of the interfaces. + */ + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + /* + * Ignore any interface for an address family other than IPv6. + */ + if (ifa->ifa_addr->sa_family != AF_INET6) { + total_interfaces++; /* Eventually may have IPv6 address later */ + continue; + } + memcpy(&addr, ifa->ifa_addr, sizeof(struct sockaddr_in6)); + + flags = ifa->ifa_flags; + if ((flags & (IFF_LOOPBACK | IFF_MULTICAST)) != IFF_MULTICAST) + continue; + + /* + * Get netmask of the address. + */ + memcpy(&mask, &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr, + sizeof(mask)); + + if (IN6_IS_ADDR_LINKLOCAL(&addr.sin6_addr)) { + addr.sin6_scope_id = if_nametoindex(ifa->ifa_name); +#ifdef __KAME__ + /* + * Hack for KAME kernel. Set sin6_scope_id field of a + * link local address and clear the index embedded in + * the address. + */ + /* clear interface index */ + addr.sin6_addr.s6_addr[2] = 0; + addr.sin6_addr.s6_addr[3] = 0; +#endif + } + + /* + * If the address is connected to the same subnet as one already + * installed in the uvifs array, just add the address to the list + * of addresses of the uvif. + */ + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { + if (strcmp(v->uv_name, ifa->ifa_name) == 0) { + add_phaddr(v, &addr, &mask); + break; + } + } + if (vifi != numvifs) + continue; + + /* + * If there is room in the uvifs array, install this interface. + */ + if (numvifs == MAXMIFS) { + log(LOG_WARNING, 0, "too many ifs, ignoring %s", ifa->ifa_name); + continue; + } + + /* + * Everyone below is a potential vif interface. + * We don't care if it has wrong configuration or not configured + * at all. + */ + total_interfaces++; + + v = &uvifs[numvifs]; + v->uv_flags = 0; + v->uv_metric = DEFAULT_METRIC; + v->uv_admetric = 0; + v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT; + v->uv_dst_addr = allpim6routers_group; + v->uv_prefix.sin6_addr = prefix; + v->uv_subnetmask = mask; + strncpy(v->uv_name, ifa->ifa_name, IFNAMSIZ); + v->uv_ifindex = if_nametoindex(v->uv_name); + v->uv_groups = (struct listaddr *)NULL; + v->uv_dvmrp_neighbors = (struct listaddr *)NULL; + NBRM_CLRALL(v->uv_nbrmap); + v->uv_querier = (struct listaddr *)NULL; + v->uv_prune_lifetime = 0; + v->uv_acl = (struct vif_acl *)NULL; + v->uv_leaf_timer = 0; + v->uv_addrs = (struct phaddr *)NULL; + v->uv_filter = (struct vif_filter *)NULL; + v->uv_pim_hello_timer = 0; + v->uv_gq_timer = 0; + v->uv_pim_neighbors = (struct pim_nbr_entry *)NULL; + v->uv_local_pref = default_source_preference; + v->uv_local_metric = default_source_metric; + add_phaddr(v, &addr, &mask); + + if (flags & IFF_POINTOPOINT) + v->uv_flags |= (VIFF_REXMIT_PRUNES | VIFF_POINT_TO_POINT); + log(LOG_INFO, 0, + "installing %s as if #%u - rate=%d", + v->uv_name, numvifs, v->uv_rate_limit); + ++numvifs; + + /* + * If the interface is not yet up, set the vifs_down flag to + * remind us to check again later. + */ + if (!(flags & IFF_UP)) { + v->uv_flags |= VIFF_DOWN; + vifs_down = TRUE; + } + } + + freeifaddrs(ifap); +#else /* !HAVE_GETIFADDRS */ ifc.ifc_len = num_ifreq * sizeof(struct ifreq); ifc.ifc_buf = calloc(ifc.ifc_len, sizeof(char)); while (ifc.ifc_buf) { @@ -91,7 +214,7 @@ config_vifs_from_kernel() if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0) log(LOG_ERR, errno, "ioctl SIOCGIFCONF"); - + /* * If the buffer was large enough to hold all the addresses * then break out, otherwise increase the buffer size and @@ -104,7 +227,7 @@ config_vifs_from_kernel() if ((num_ifreq * sizeof(struct ifreq)) >= ifc.ifc_len + sizeof(struct ifreq)) break; - + num_ifreq *= 2; ifc.ifc_len = num_ifreq * sizeof(struct ifreq); newbuf = realloc(ifc.ifc_buf, ifc.ifc_len); @@ -114,7 +237,7 @@ config_vifs_from_kernel() } if (ifc.ifc_buf == NULL) log(LOG_ERR, 0, "config_vifs_from_kernel: ran out of memory"); - + ifrp = (struct ifreq *)ifc.ifc_buf; ifend = (struct ifreq *)(ifc.ifc_buf + ifc.ifc_len); /* @@ -130,7 +253,7 @@ config_vifs_from_kernel() #else n = sizeof(*ifrp); #endif /* HAVE_SA_LEN */ - + /* * Ignore any interface for an address family other than IPv6. */ @@ -140,7 +263,7 @@ config_vifs_from_kernel() } memcpy(&addr, &ifrp->ifr_addr, sizeof(struct sockaddr_in6)); - + /* * Need a template to preserve address info that is * used below to locate the next entry. (Otherwise, @@ -211,18 +334,12 @@ config_vifs_from_kernel() * at all. */ total_interfaces++; - + v = &uvifs[numvifs]; v->uv_flags = 0; v->uv_metric = DEFAULT_METRIC; v->uv_admetric = 0; -#if 0 - v->uv_threshold = DEFAULT_THRESHOLD; -#endif v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT; -#if 0 - v->uv_rmt_addr = INADDR_ANY_N; -#endif v->uv_dst_addr = allpim6routers_group; v->uv_prefix.sin6_addr = prefix; v->uv_subnetmask = mask; @@ -243,14 +360,14 @@ config_vifs_from_kernel() v->uv_local_pref = default_source_preference; v->uv_local_metric = default_source_metric; add_phaddr(v, &addr, &mask); - + if (flags & IFF_POINTOPOINT) v->uv_flags |= (VIFF_REXMIT_PRUNES | VIFF_POINT_TO_POINT); log(LOG_INFO, 0, "installing %s as if #%u - rate=%d", v->uv_name, numvifs, v->uv_rate_limit); ++numvifs; - + /* * If the interface is not yet up, set the vifs_down flag to * remind us to check again later. @@ -260,6 +377,7 @@ config_vifs_from_kernel() vifs_down = TRUE; } } +#endif /* HAVE_GETIFADDRS */ } static void @@ -316,12 +434,12 @@ ifname2mifi(ifname) return(mifi); } -#define UNKNOWN -1 -#define EMPTY 1 -#define PHYINT 2 -#define DEFAULT_SOURCE_METRIC 3 -#define DEFAULT_SOURCE_PREFERENCE 4 -#define FILTER 5 +#define UNKNOWN -1 +#define EMPTY 1 +#define PHYINT 2 +#define DEFAULT_SOURCE_METRIC 3 +#define DEFAULT_SOURCE_PREFERENCE 4 +#define FILTER 5 /* * function name: wordToOption @@ -330,7 +448,7 @@ ifname2mifi(ifname) * operation: converts the result of the string comparisons into numerics. * comments: called by config_vifs_from_file() */ -static int +static int wordToOption(word) char *word; { @@ -363,13 +481,13 @@ parse_phyint(s) vifi_t vifi; struct uvif *v; u_int n; - + if (EQUAL((w = next_word(&s)), "")) { log(LOG_WARNING, 0, "Missing phyint in %s", configfilename); return(FALSE); } /* if empty */ ifname = w; - + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (vifi == numvifs) { log(LOG_WARNING, 0, @@ -380,14 +498,14 @@ parse_phyint(s) if (strcmp(v->uv_name, ifname)) continue; - + while (!EQUAL((w = next_word(&s)), "")) { if (EQUAL(w, "disable")) v->uv_flags |= VIFF_DISABLED; else if (EQUAL(w, "nolistener")) v->uv_flags |= VIFF_NOLISTENER; else if(EQUAL(w, "preference")) { - if(EQUAL((w = next_word(&s)), "")) + if(EQUAL((w = next_word(&s)), "")) log(LOG_WARNING, 0, "Missing preference for phyint %s in %s", ifname, configfilename); @@ -400,13 +518,13 @@ parse_phyint(s) else { IF_DEBUG(DEBUG_ASSERT) log(LOG_DEBUG, 0, - "Config setting default local preference on %s to %d.", + "Config setting default local preference on %s to %d.", ifname, n); v->uv_local_pref = n; } - + } else if(EQUAL(w, "metric")) { - if(EQUAL((w = next_word(&s)), "")) + if(EQUAL((w = next_word(&s)), "")) log(LOG_WARNING, 0, "Missing metric for phyint %s in %s", ifname, configfilename); @@ -419,7 +537,7 @@ parse_phyint(s) else { IF_DEBUG(DEBUG_ASSERT) log(LOG_DEBUG, 0, - "Config setting default local metric on %s to %d.", + "Config setting default local metric on %s to %d.", ifname, n); v->uv_local_metric = n; } @@ -526,7 +644,7 @@ parse_filter(s) * output: int * operation: reads and assigns the default source metric, if no reliable * unicast routing information available. - * General form: + * General form: * 'default_source_metric <number>'. * default pref and metric statements should precede all phyint * statements in the config file. @@ -557,7 +675,7 @@ parse_default_source_metric(s) for (vifi = 0, v = uvifs; vifi < MAXMIFS; ++vifi, ++v) { v->uv_local_metric = default_source_metric; } - + return(TRUE); } @@ -568,7 +686,7 @@ parse_default_source_metric(s) * output: int * operation: reads and assigns the default source preference, if no reliable * unicast routing information available. - * General form: + * General form: * 'default_source_preference <number>'. * default pref and metric statements should precede all phyint * statements in the config file. @@ -604,27 +722,20 @@ parse_default_source_preference(s) } #endif -void +void config_vifs_from_file() { FILE *f; char linebuf[100]; char *w, *s; - struct ifconf ifc; int option; - char ifbuf[BUFSIZ]; if ((f = fopen(configfilename, "r")) == NULL) { - if (errno != ENOENT) log(LOG_WARNING, errno, "can't open %s", + if (errno != ENOENT) log(LOG_WARNING, errno, "can't open %s", configfilename); return; } - ifc.ifc_buf = ifbuf; - ifc.ifc_len = sizeof(ifbuf); - if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0) - log(LOG_ERR, errno, "ioctl SIOCGIFCONF"); - while (fgets(linebuf, sizeof(linebuf), f) != NULL) { s = linebuf; w = next_word(&s); @@ -652,11 +763,11 @@ next_word(s) char **s; { char *w; - + w = *s; while (*w == ' ' || *w == '\t') w++; - + *s = w; for(;;) { switch (**s) { diff --git a/usr.sbin/pim6dd/debug.c b/usr.sbin/pim6dd/debug.c index 0894d5c29090e..392beaae4739e 100644 --- a/usr.sbin/pim6dd/debug.c +++ b/usr.sbin/pim6dd/debug.c @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,10 +31,10 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * - * $Id: debug.c,v 1.4 1999/09/20 14:28:08 jinmei Exp $ + * $Id: debug.c,v 1.8 2000/05/18 12:47:59 itojun Exp $ */ /* * Part of this program has been derived from mrouted. @@ -67,6 +67,38 @@ unsigned long debug = 0x00000000; /* If (long) is smaller than static char dumpfilename[] = _PATH_PIM6D_DUMP; static char cachefilename[] = _PATH_PIM6D_CACHE; /* TODO: notused */ +static char *sec2str __P((time_t)); + +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); +} char * packet_kind(proto, type, code) @@ -160,7 +192,7 @@ log_level(proto, type, code) default: return LOG_WARNING; } - + case IPPROTO_PIM: /* PIM v2 */ switch (type) { @@ -178,18 +210,18 @@ log_level(proto, type, code) * Dump internal data structures to stderr. */ /* TODO: currently not used -void +void dump(int i) { dump_vifs(stderr); dump_pim_mrt(stderr); -} +} */ /* * Dump internal data structures to a file. */ -void +void fdump(i) int i; { @@ -197,6 +229,7 @@ fdump(i) fp = fopen(dumpfilename, "w"); if (fp != NULL) { dump_vifs(fp); + dump_mldqueriers(fp); dump_pim_mrt(fp); dump_lcl_grp(fp); (void) fclose(fp); @@ -212,11 +245,11 @@ cdump(i) int i; { FILE *fp; - + fp = fopen(cachefilename, "w"); if (fp != NULL) { /* TODO: implement it: - dump_cache(fp); + dump_cache(fp); */ (void) fclose(fp); } @@ -225,7 +258,7 @@ cdump(i) void dump_vifs(fp) FILE *fp; -{ +{ vifi_t vifi; register struct uvif *v; pim_nbr_entry_t *n; @@ -236,7 +269,7 @@ dump_vifs(fp) fprintf(fp, "\nMulticast Interface Table\n %-4s %-6s %-50s %-14s %s", "Mif", " PhyIF", "Local-Address/Prefixlen", "Flags", "Neighbors\n"); - + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { int firstaddr = 1; for (pa = v->uv_addrs; pa; pa = pa->pa_next) { @@ -280,11 +313,13 @@ dump_vifs(fp) fprintf(fp, " DVMRP"); width += 6; } -#endif +#endif if (v->uv_flags & VIFF_NONBRS) { fprintf(fp, " %-12s", "NO-NBR"); width += 6; } + if (v->uv_flags & VIFF_QUERIER) + fprintf(fp, " QRY"); if ((n = v->uv_pim_neighbors) != NULL) { /* Print the first neighbor on the same line */ @@ -295,7 +330,7 @@ dump_vifs(fp) for (n = n->next; n != NULL; n = n->next) fprintf(fp, "%64s %-15s\n", "", inet6_fmt(&n->address.sin6_addr)); - + } else fprintf(fp, "\n"); @@ -319,7 +354,7 @@ log(int severity, int syserr, char *format, ...) char *msg; struct timeval now; struct tm *thyme; - + va_start(ap, format); #else /*VARARGS3*/ @@ -335,13 +370,13 @@ log(severity, syserr, format, va_alist) char tbuf[20]; struct timeval now; struct tm *thyme; - + va_start(ap); #endif vsprintf(&fmt[10], format, ap); va_end(ap); msg = (severity == LOG_WARNING) ? fmt : &fmt[10]; - + /* * Log to stderr if we haven't forked yet and it's a warning or worse, * or if we're debugging. @@ -354,7 +389,8 @@ log(severity, syserr, format, va_alist) if (!debug) fprintf(stderr, "%s: ", progname); fprintf(stderr, "%02d:%02d:%02d.%03ld %s", thyme->tm_hour, - thyme->tm_min, thyme->tm_sec, now.tv_usec / 1000, msg); + thyme->tm_min, thyme->tm_sec, (long int)now.tv_usec / 1000, + msg); if (syserr == 0) fprintf(stderr, "\n"); else if (syserr < sys_nerr) @@ -362,7 +398,7 @@ log(severity, syserr, format, va_alist) else fprintf(stderr, ": errno %d\n", syserr); } - + /* * Always log things that are worse than warnings, no matter what * the log_nmsgs rate limiter says. @@ -380,12 +416,41 @@ log(severity, syserr, format, va_alist) } else syslog(severity, "%s", msg); } - + if (severity <= LOG_ERR) exit(-1); } -/* TODO: format the output for better readability */ void +dump_mldqueriers(fp) + FILE *fp; +{ + struct uvif *v; + vifi_t vifi; + time_t now; + + fprintf(fp, "MLD Querier List\n"); + fprintf(fp, " %-3s %6s %-40s %-5s %15s\n", + "Mif", "PhyIF", "Address", "Timer", "Last"); + (void)time(&now); + + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { + if (v->uv_querier) { + fprintf(fp, " %-3u %6s", vifi, + (v->uv_flags & MIFF_REGISTER) ? "regist": + v->uv_name); + + fprintf(fp, " %-40s %5lu %15s\n", + inet6_fmt(&v->uv_querier->al_addr.sin6_addr), + (u_long)v->uv_querier->al_timer, + sec2str(now - v->uv_querier->al_ctime)); + } + } + + fprintf(fp, "\n"); +} + +/* TODO: format the output for better readability */ +void dump_pim_mrt(fp) FILE *fp; { @@ -399,8 +464,8 @@ dump_pim_mrt(fp) char leaves_oifs[(sizeof(if_set)<<3)+1]; char filter_oifs[(sizeof(if_set)<<3)+1]; char incoming_iif[(sizeof(if_set)<<3)+1]; - - fprintf(fp, "Multicast Routing Table\n%s", + + fprintf(fp, "Multicast Routing Table\n%s", " Source Group Flags\n"); /* TODO: remove the dummy 0:: group (first in the chain) */ @@ -446,7 +511,7 @@ dump_pim_mrt(fp) if (r->flags & MRTF_SG) fprintf(fp, " SG"); if (r->flags & MRTF_PMBR) fprintf(fp, " PMBR"); fprintf(fp, "\n"); - + fprintf(fp, "Pruned oifs: %-20s\n", pruned_oifs); fprintf(fp, "Asserted oifs: %-20s\n", pruned_oifs); fprintf(fp, "Filtered oifs: %-20s\n", filter_oifs); @@ -454,7 +519,7 @@ dump_pim_mrt(fp) fprintf(fp, "Outgoing oifs: %-20s\n", oifs); fprintf(fp, "Incoming : %-20s\n", incoming_iif); - fprintf(fp, "Upstream nbr: %s\n", + fprintf(fp, "Upstream nbr: %s\n", r->upstream ? inet6_fmt(&r->upstream->address.sin6_addr) : "NONE"); fprintf(fp, "\nTIMERS: Entry Prune VIFS:"); for (vifi = 0; vifi < numvifs; vifi++) diff --git a/usr.sbin/pim6dd/debug.h b/usr.sbin/pim6dd/debug.h index fbcc708d4ed15..1d4e294f4ae98 100644 --- a/usr.sbin/pim6dd/debug.h +++ b/usr.sbin/pim6dd/debug.h @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,7 +31,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: debug.h,v 1.1.1.1 1999/08/08 23:30:52 itojun Exp $ @@ -49,70 +49,70 @@ extern unsigned long debug; extern int log_nmsgs; -#define IF_DEBUG(l) if (debug && debug & (l)) +#define IF_DEBUG(l) if (debug && debug & (l)) -#define LOG_MAX_MSGS 20 /* if > 20/minute then shut up for a while */ -#define LOG_SHUT_UP 600 /* shut up for 10 minutes */ +#define LOG_MAX_MSGS 20 /* if > 20/minute then shut up for a while */ +#define LOG_SHUT_UP 600 /* shut up for 10 minutes */ /* Debug values definition */ /* DVMRP reserved for future use */ -#define DEBUG_DVMRP_PRUNE 0x00000001 -#define DEBUG_DVMRP_ROUTE 0x00000002 -#define DEBUG_DVMRP_PEER 0x00000004 -#define DEBUG_DVMRP_TIMER 0x00000008 -#define DEBUG_DVMRP_DETAIL 0x01000000 -#define DEBUG_DVMRP ( DEBUG_DVMRP_PRUNE | DEBUG_DVMRP_ROUTE | \ +#define DEBUG_DVMRP_PRUNE 0x00000001 +#define DEBUG_DVMRP_ROUTE 0x00000002 +#define DEBUG_DVMRP_PEER 0x00000004 +#define DEBUG_DVMRP_TIMER 0x00000008 +#define DEBUG_DVMRP_DETAIL 0x01000000 +#define DEBUG_DVMRP ( DEBUG_DVMRP_PRUNE | DEBUG_DVMRP_ROUTE | \ DEBUG_DVMRP_PEER ) /* MLD related */ -#define DEBUG_MLD_PROTO 0x00000010 -#define DEBUG_MLD_TIMER 0x00000020 -#define DEBUG_MLD_MEMBER 0x00000040 -#define DEBUG_MEMBER DEBUG_MLD_MEMBER -#define DEBUG_MLD ( DEBUG_MLD_PROTO | DEBUG_MLD_TIMER | \ +#define DEBUG_MLD_PROTO 0x00000010 +#define DEBUG_MLD_TIMER 0x00000020 +#define DEBUG_MLD_MEMBER 0x00000040 +#define DEBUG_MEMBER DEBUG_MLD_MEMBER +#define DEBUG_MLD ( DEBUG_MLD_PROTO | DEBUG_MLD_TIMER | \ DEBUG_MLD_MEMBER ) /* Misc */ -#define DEBUG_TRACE 0x00000080 -#define DEBUG_TIMEOUT 0x00000100 -#define DEBUG_PKT 0x00000200 +#define DEBUG_TRACE 0x00000080 +#define DEBUG_TIMEOUT 0x00000100 +#define DEBUG_PKT 0x00000200 /* Kernel related */ -#define DEBUG_IF 0x00000400 -#define DEBUG_KERN 0x00000800 -#define DEBUG_MFC 0x00001000 -#define DEBUG_RSRR 0x00002000 +#define DEBUG_IF 0x00000400 +#define DEBUG_KERN 0x00000800 +#define DEBUG_MFC 0x00001000 +#define DEBUG_RSRR 0x00002000 /* PIM related */ -#define DEBUG_PIM_GRAFT 0x02000000 -#define DEBUG_PIM_HELLO 0x00004000 -#define DEBUG_PIM_REGISTER 0x00008000 -#define DEBUG_PIM_JOIN_PRUNE 0x00010000 -#define DEBUG_PIM_BOOTSTRAP 0x00020000 -#define DEBUG_PIM_ASSERT 0x00040000 -#define DEBUG_PIM_CAND_RP 0x00080000 -#define DEBUG_PIM_MRT 0x00100000 -#define DEBUG_PIM_TIMER 0x00200000 -#define DEBUG_PIM_RPF 0x00400000 -#define DEBUG_RPF DEBUG_PIM_RPF -#define DEBUG_PIM_DETAIL 0x00800000 -#define DEBUG_PIM ( DEBUG_PIM_HELLO | DEBUG_PIM_REGISTER | \ +#define DEBUG_PIM_GRAFT 0x02000000 +#define DEBUG_PIM_HELLO 0x00004000 +#define DEBUG_PIM_REGISTER 0x00008000 +#define DEBUG_PIM_JOIN_PRUNE 0x00010000 +#define DEBUG_PIM_BOOTSTRAP 0x00020000 +#define DEBUG_PIM_ASSERT 0x00040000 +#define DEBUG_PIM_CAND_RP 0x00080000 +#define DEBUG_PIM_MRT 0x00100000 +#define DEBUG_PIM_TIMER 0x00200000 +#define DEBUG_PIM_RPF 0x00400000 +#define DEBUG_RPF DEBUG_PIM_RPF +#define DEBUG_PIM_DETAIL 0x00800000 +#define DEBUG_PIM ( DEBUG_PIM_HELLO | DEBUG_PIM_REGISTER | \ DEBUG_PIM_JOIN_PRUNE | DEBUG_PIM_BOOTSTRAP | \ DEBUG_PIM_ASSERT | DEBUG_PIM_CAND_RP | \ DEBUG_PIM_MRT | DEBUG_PIM_TIMER | \ - DEBUG_PIM_RPF | DEBUG_PIM_GRAFT ) + DEBUG_PIM_RPF | DEBUG_PIM_GRAFT ) -#define DEBUG_MRT ( DEBUG_DVMRP_ROUTE | DEBUG_PIM_MRT ) -#define DEBUG_NEIGHBORS ( DEBUG_DVMRP_PEER | DEBUG_PIM_HELLO ) -#define DEBUG_TIMER ( DEBUG_MLD_TIMER | DEBUG_DVMRP_TIMER | \ +#define DEBUG_MRT ( DEBUG_DVMRP_ROUTE | DEBUG_PIM_MRT ) +#define DEBUG_NEIGHBORS ( DEBUG_DVMRP_PEER | DEBUG_PIM_HELLO ) +#define DEBUG_TIMER ( DEBUG_MLD_TIMER | DEBUG_DVMRP_TIMER | \ DEBUG_PIM_TIMER ) -#define DEBUG_ASSERT ( DEBUG_PIM_ASSERT ) -#define DEBUG_ALL 0xffffffff +#define DEBUG_ASSERT ( DEBUG_PIM_ASSERT ) +#define DEBUG_ALL 0xffffffff -#define DEBUG_DEFAULT 0xffffffff/* default if "-d" given without value */ +#define DEBUG_DEFAULT 0xffffffff/* default if "-d" given without value */ diff --git a/usr.sbin/pim6dd/defs.h b/usr.sbin/pim6dd/defs.h index 5970c7428dd8f..24e0d242ac6c4 100644 --- a/usr.sbin/pim6dd/defs.h +++ b/usr.sbin/pim6dd/defs.h @@ -10,15 +10,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -30,22 +30,22 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * - * $Id: defs.h,v 1.6 1999/12/10 06:09:13 itojun Exp $ + * $Id: defs.h,v 1.7 2000/04/30 13:01:36 itojun Exp $ */ /* * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * @@ -54,12 +54,12 @@ #include <stdio.h> #include <stdlib.h> -#include <unistd.h> +#include <unistd.h> #include <ctype.h> #include <errno.h> #include <syslog.h> -#include <signal.h> -#include <string.h> +#include <signal.h> +#include <string.h> #include <sys/param.h> #include <sys/types.h> #include <sys/socket.h> @@ -70,7 +70,9 @@ #endif /* SYSV || __bsdi__ || SunOS 4.x */ #include <sys/time.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_systm.h> #include <netinet/ip.h> @@ -80,10 +82,14 @@ #include <netinet/ip6.h> #include <arpa/inet.h> +#ifdef __FreeBSD__ /* sigh */ #include <osreldate.h> -#define rtentry kernel_rtentry +#endif /* __FreeBSD__ */ +#if (defined(__bsdi__)) || (defined(__FreeBSD__) && (__FreeBSD_version >= 220000)) +#define rtentry kernel_rtentry #include <net/route.h> #undef rtentry +#endif /* __bsdi__ or __FreeBSD_version >= 220000 */ #include <netinet/ip_mroute.h> #include <netinet6/ip6_mroute.h> #include <strings.h> @@ -97,9 +103,9 @@ typedef u_char u_int8; #ifndef __P #ifdef __STDC__ -#define __P(x) x +#define __P(x) x #else -#define __P(x) () +#define __P(x) () #endif #endif @@ -122,46 +128,46 @@ typedef void (*ihfunc_t) __P((int, fd_set *)); */ /* #if (!(defined(__bsdi__)) && !(defined(KERNEL))) */ #ifndef KERNEL -#define max(a, b) ((a) < (b) ? (b) : (a)) -#define min(a, b) ((a) > (b) ? (b) : (a)) +#define max(a, b) ((a) < (b) ? (b) : (a)) +#define min(a, b) ((a) > (b) ? (b) : (a)) #endif /* * Various definitions to make it working for different platforms */ /* The old style sockaddr definition doesn't have sa_len */ -#if (defined(BSD) && (BSD >= 199006)) /* sa_len was added with 4.3-Reno */ -#define HAVE_SA_LEN +#if (defined(BSD) && (BSD >= 199006)) /* sa_len was added with 4.3-Reno */ +#define HAVE_SA_LEN #endif /* Versions of Solaris older than 2.6 don't have routing sockets. */ /* XXX TODO: check FreeBSD version and add all other platforms */ #if ((defined(SunOS) && SunOS >=56) || (defined __FreeBSD__) || (defined IRIX) || (defined __bsdi__) || defined(__NetBSD__)) -#define HAVE_ROUTING_SOCKETS +#define HAVE_ROUTING_SOCKETS #endif -#define TRUE 1 -#define FALSE 0 +#define TRUE 1 +#define FALSE 0 -#define CREATE TRUE -#define DONT_CREATE FALSE +#define CREATE TRUE +#define DONT_CREATE FALSE -#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0) +#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0) /* obnoxious gcc gives an extraneous warning about this constant... */ #if defined(__STDC__) || defined(__GNUC__) -#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ +#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ #else -#define JAN_1970 2208988800L /* 1970 - 1900 in seconds */ -#define const /**/ +#define JAN_1970 2208988800L /* 1970 - 1900 in seconds */ +#define const /**/ #endif -#define MINHLIM 1 /* min hoplim in the packets send locally */ +#define MINHLIM 1 /* min hoplim in the packets send locally */ -#define MAX_IP_PACKET_LEN 576 -#define MIN_IP_HEADER_LEN 20 -#define MAX_IP_HEADER_LEN 60 +#define MAX_IP_PACKET_LEN 576 +#define MIN_IP_HEADER_LEN 20 +#define MAX_IP_HEADER_LEN 60 /* @@ -170,48 +176,48 @@ typedef void (*ihfunc_t) __P((int, fd_set *)); */ #ifndef INADDR_ALLRTRS_GROUP /* address for multicast mtrace msg */ -#define INADDR_ALLRTRS_GROUP (u_int32)0xe0000002 /* 224.0.0.2 */ +#define INADDR_ALLRTRS_GROUP (u_int32)0xe0000002 /* 224.0.0.2 */ #endif #ifndef INADDR_MAX_LOCAL_GROUP define INADDR_MAX_LOCAL_GROUP (u_int32)0xe00000ff /* 224.0.0.255 */ #endif -#define INADDR_ANY_N (u_int32)0x00000000 /* INADDR_ANY in +#define INADDR_ANY_N (u_int32)0x00000000 /* INADDR_ANY in * network order */ -#define CLASSD_PREFIX (u_int32)0xe0000000 /* 224.0.0.0 */ -#define ALL_MCAST_GROUPS_ADDR (u_int32)0xe0000000 /* 224.0.0.0 */ -#define ALL_MCAST_GROUPS_LENGTH 4 +#define CLASSD_PREFIX (u_int32)0xe0000000 /* 224.0.0.0 */ +#define ALL_MCAST_GROUPS_ADDR (u_int32)0xe0000000 /* 224.0.0.0 */ +#define ALL_MCAST_GROUPS_LENGTH 4 /* Used by DVMRP */ -#define DEFAULT_METRIC 1 /* default subnet/tunnel metric */ -#define DEFAULT_THRESHOLD 1 /* default subnet/tunnel threshold */ +#define DEFAULT_METRIC 1 /* default subnet/tunnel metric */ +#define DEFAULT_THRESHOLD 1 /* default subnet/tunnel threshold */ -#define TIMER_INTERVAL 5 /* 5 sec virtual timer granularity */ +#define TIMER_INTERVAL 5 /* 5 sec virtual timer granularity */ #ifdef RSRR -#define BIT_ZERO(X) ((X) = 0) -#define BIT_SET(X,n) ((X) |= 1 << (n)) -#define BIT_CLR(X,n) ((X) &= ~(1 << (n))) -#define BIT_TST(X,n) ((X) & 1 << (n)) +#define BIT_ZERO(X) ((X) = 0) +#define BIT_SET(X,n) ((X) |= 1 << (n)) +#define BIT_CLR(X,n) ((X) &= ~(1 << (n))) +#define BIT_TST(X,n) ((X) & 1 << (n)) #endif /* RSRR */ #ifdef SYSV -#define bcopy(a, b, c) memcpy((b), (a), (c)) -#define bzero(s, n) memset((s), 0, (n)) -#define setlinebuf(s) setvbuf((s), (NULL), (_IOLBF), 0) -#define RANDOM() lrand48() +#define bcopy(a, b, c) memcpy((b), (a), (c)) +#define bzero(s, n) memset((s), 0, (n)) +#define setlinebuf(s) setvbuf((s), (NULL), (_IOLBF), 0) +#define RANDOM() lrand48() #else -#define RANDOM() random() +#define RANDOM() random() #endif /* SYSV */ /* * External declarations for global variables and functions. */ -#define RECV_BUF_SIZE 64*1024 /* Maximum buff size to send +#define RECV_BUF_SIZE 64*1024 /* Maximum buff size to send * or receive packet */ -#define SO_RECV_BUF_SIZE_MAX 256*1024 -#define SO_RECV_BUF_SIZE_MIN 48*1024 +#define SO_RECV_BUF_SIZE_MAX 256*1024 +#define SO_RECV_BUF_SIZE_MIN 48*1024 /* TODO: describe the variables and clean up */ extern char *mld6_recv_buf; @@ -259,41 +265,41 @@ extern char * sys_errlist[]; #ifndef IGMP_MEMBERSHIP_QUERY -#define IGMP_MEMBERSHIP_QUERY IGMP_HOST_MEMBERSHIP_QUERY +#define IGMP_MEMBERSHIP_QUERY IGMP_HOST_MEMBERSHIP_QUERY #if !(defined(__NetBSD__)) -#define IGMP_V1_MEMBERSHIP_REPORT IGMP_HOST_MEMBERSHIP_REPORT -#define IGMP_V2_MEMBERSHIP_REPORT IGMP_HOST_NEW_MEMBERSHIP_REPORT +#define IGMP_V1_MEMBERSHIP_REPORT IGMP_HOST_MEMBERSHIP_REPORT +#define IGMP_V2_MEMBERSHIP_REPORT IGMP_HOST_NEW_MEMBERSHIP_REPORT #else -#define IGMP_V1_MEMBERSHIP_REPORT IGMP_v1_HOST_MEMBERSHIP_REPORT -#define IGMP_V2_MEMBERSHIP_REPORT IGMP_v2_HOST_MEMBERSHIP_REPORT +#define IGMP_V1_MEMBERSHIP_REPORT IGMP_v1_HOST_MEMBERSHIP_REPORT +#define IGMP_V2_MEMBERSHIP_REPORT IGMP_v2_HOST_MEMBERSHIP_REPORT #endif -#define IGMP_V2_LEAVE_GROUP IGMP_HOST_LEAVE_MESSAGE +#define IGMP_V2_LEAVE_GROUP IGMP_HOST_LEAVE_MESSAGE #endif #if defined(__NetBSD__) -#define IGMP_MTRACE_RESP IGMP_MTRACE_REPLY -#define IGMP_MTRACE IGMP_MTRACE_QUERY +#define IGMP_MTRACE_RESP IGMP_MTRACE_REPLY +#define IGMP_MTRACE IGMP_MTRACE_QUERY #endif /* For timeout. The timers count down */ -#define SET_TIMER(timer, value) (timer) = (value) -#define IF_TIMER_SET(timer) if ((timer) > 0) -#define IF_TIMER_NOT_SET(timer) if ((timer) <= 0) -#define FIRE_TIMER(timer) (timer) = 0 +#define SET_TIMER(timer, value) (timer) = (value) +#define IF_TIMER_SET(timer) if ((timer) > 0) +#define IF_TIMER_NOT_SET(timer) if ((timer) <= 0) +#define FIRE_TIMER(timer) (timer) = 0 -#define IF_TIMEOUT(value) \ +#define IF_TIMEOUT(value) \ if (!(((value) >= TIMER_INTERVAL) && ((value) -= TIMER_INTERVAL))) -#define IF_NOT_TIMEOUT(value) \ +#define IF_NOT_TIMEOUT(value) \ if (((value) >= TIMER_INTERVAL) && ((value) -= TIMER_INTERVAL)) -#define TIMEOUT(value) \ +#define TIMEOUT(value) \ (!(((value) >= TIMER_INTERVAL) && ((value) -= TIMER_INTERVAL))) -#define NOT_TIMEOUT(value) \ +#define NOT_TIMEOUT(value) \ (((value) >= TIMER_INTERVAL) && ((value) -= TIMER_INTERVAL)) -#define ELSE else /* To make emacs cc-mode happy */ +#define ELSE else /* To make emacs cc-mode happy */ /* @@ -317,6 +323,7 @@ extern void config_vifs_from_file __P((void)); extern char *packet_kind __P((u_int proto, u_int type, u_int code)); extern int debug_kind __P((u_int proto, u_int type, u_int code)); extern void log __P((int, int, char *, ...)); +extern void dump_mldqueriers __P((FILE *)); extern int log_level __P((u_int proto, u_int type, u_int code)); extern void dump __P((int i)); extern void fdump __P((int i)); @@ -386,7 +393,7 @@ extern void accept_group_report __P((u_int32 src, u_int32 dst, u_int32 group, int r_type)); extern void accept_leave_message __P((u_int32 src, u_int32 dst, u_int32 group)); -#endif +#endif #if 0 /* inet.c */ @@ -482,7 +489,7 @@ extern int receive_pim6_join_prune __P((struct sockaddr_in6 *src, char *pim_message, int datalen)); extern int send_pim6_jp __P((mrtentry_t *mrtentry_ptr, int action, mifi_t mifi, - struct sockaddr_in6 *target_addr, + struct sockaddr_in6 *target_addr, u_int16 holdtime, int echo)); extern int receive_pim6_assert __P((struct sockaddr_in6 *src, @@ -512,7 +519,7 @@ extern void delete_pim_nbr __P((pim_nbr_entry_t *nbr_delete)); extern int receive_pim_join_prune __P((u_int32 src, u_int32 dst, char *pim_message, int datalen)); extern int send_pim_jp __P((mrtentry_t *mrtentry_ptr, int action, - vifi_t vifi, u_int32 target_addr, + vifi_t vifi, u_int32 target_addr, u_int16 holdtime)); extern int receive_pim_assert __P((u_int32 src, u_int32 dst, char *pim_message, int datalen)); @@ -520,7 +527,7 @@ extern int send_pim_assert __P((u_int32 source, u_int32 group, vifi_t vifi, mrtentry_t *mrtentry_ptr)); extern void delete_pim_graft_entry __P((mrtentry_t *mrtentry_ptr)); -extern int receive_pim_graft __P((u_int32 src, u_int32 dst, +extern int receive_pim_graft __P((u_int32 src, u_int32 dst, char *pim_message, int datalen, int pimtype)); #endif @@ -562,9 +569,9 @@ extern int init_routesock __P((void)); #endif /* HAVE_ROUTING_SOCKETS */ #ifdef RSRR -#define gtable mrtentry -#define RSRR_NOTIFICATION_OK TRUE -#define RSRR_NOTIFICATION_FALSE FALSE +#define gtable mrtentry +#define RSRR_NOTIFICATION_OK TRUE +#define RSRR_NOTIFICATION_FALSE FALSE /* rsrr.c */ extern void rsrr_init __P((void)); diff --git a/usr.sbin/pim6dd/inet6.c b/usr.sbin/pim6dd/inet6.c index 7dc9ace0191e4..3caddfd7020f5 100644 --- a/usr.sbin/pim6dd/inet6.c +++ b/usr.sbin/pim6dd/inet6.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -211,7 +211,7 @@ inet6_fmt(struct in6_addr *addr) static char ip6buf[8][INET6_ADDRSTRLEN]; static int ip6round = 0; char *cp; - + ip6round = (ip6round + 1) & 7; cp = ip6buf[ip6round]; @@ -274,7 +274,7 @@ net6name(struct in6_addr *prefix, struct in6_addr *mask) static char ip6buf[8][INET6_ADDRSTRLEN + 4]; /* length of addr/plen */ static int ip6round = 0; char *cp; - + ip6round = (ip6round + 1) & 7; cp = ip6buf[ip6round]; diff --git a/usr.sbin/pim6dd/kern.c b/usr.sbin/pim6dd/kern.c index 170e85e840294..69118dc8d14c2 100644 --- a/usr.sbin/pim6dd/kern.c +++ b/usr.sbin/pim6dd/kern.c @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,7 +31,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: kern.c,v 1.1.1.1 1999/08/08 23:30:52 itojun Exp $ @@ -57,18 +57,18 @@ int curttl = 0; /* * Open/init the multicast routing in the kernel and sets the MRT_ASSERT * flag in the kernel. - * + * */ void k_init_pim(socket) int socket; { int v = 1; - + if (setsockopt(socket, IPPROTO_IPV6, MRT6_INIT, (char *)&v, sizeof(int)) < 0) log(LOG_ERR, errno, "cannot enable multicast routing in kernel"); - + if(setsockopt(socket, IPPROTO_IPV6, MRT6_PIM, (char *)&v, sizeof(int)) < 0) log(LOG_ERR, errno, "cannot set ASSERT flag in kernel"); @@ -91,7 +91,7 @@ k_stop_pim(socket) if (setsockopt(socket, IPPROTO_IPV6, MRT6_DONE, (char *)NULL, 0) < 0) log(LOG_ERR, errno, "cannot disable multicast routing in kernel"); - + } @@ -106,7 +106,7 @@ void k_set_rcvbuf(socket, bufsize, minsize) { int delta = bufsize / 2; int iter = 0; - + /* * Set the socket buffer. If we can't set it as large as we * want, search around to try to find the highest acceptable @@ -120,7 +120,7 @@ void k_set_rcvbuf(socket, bufsize, minsize) iter++; if (delta > 1) delta /= 2; - + if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, sizeof(bufsize)) < 0) { bufsize -= delta; @@ -174,7 +174,7 @@ void k_set_hlim(socket, h) curttl = h; #else int hlim = h; - + if (setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hlim, sizeof(hlim)) < 0) log(LOG_ERR, errno, "setsockopt IPV6_MULTICAST_HOPS %u", hlim); @@ -222,7 +222,7 @@ void k_join(socket, grp, ifindex) u_int ifindex; { struct ipv6_mreq mreq; - + mreq.ipv6mr_multiaddr = *grp; mreq.ipv6mr_interface = ifindex; @@ -245,7 +245,7 @@ void k_leave(socket, grp, ifindex) mreq.ipv6mr_multiaddr = *grp; mreq.ipv6mr_interface = ifindex; - + if (setsockopt(socket, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char *)&mreq, sizeof(mreq)) < 0) log(LOG_WARNING, errno, "cannot leave group %s on interface %s", @@ -304,13 +304,13 @@ k_del_mfc(socket, source, group) mc.mf6cc_origin = *source; mc.mf6cc_mcastgrp = *group; - + if (setsockopt(socket, IPPROTO_IPV6, MRT6_DEL_MFC, (char *)&mc, sizeof(mc)) < 0) { log(LOG_WARNING, errno, "setsockopt MRT6_DEL_MFC"); return FALSE; } - + IF_DEBUG(DEBUG_MFC) log(LOG_DEBUG, 0, "Deleted MFC entry: src %s, grp %s", inet6_fmt(&source->sin6_addr), @@ -345,7 +345,7 @@ k_chg_mfc(socket, source, group, iif, oifs) else IF_CLR(vifi, &mc.mf6cc_ifset); } - + if (setsockopt(socket, IPPROTO_IPV6, MRT6_ADD_MFC, (char *)&mc, sizeof(mc)) < 0) { log(LOG_WARNING, errno, @@ -368,7 +368,7 @@ int k_get_vif_count(vifi, retval) struct vif_count *retval; { struct sioc_mif_req6 mreq; - + mreq.mifi = vifi; if (ioctl(udp_socket, SIOCGETMIFCNT_IN6, (char *)&mreq) < 0) { log(LOG_WARNING, errno, "SIOCGETMIFCNT_IN6 on vif %d", vifi); @@ -396,7 +396,7 @@ k_get_sg_cnt(socket, source, group, retval) struct sg_count *retval; { struct sioc_sg_req6 sgreq; - + sgreq.src = *source; sgreq.grp = *group; if (ioctl(socket, SIOCGETSGCNT_IN6, (char *)&sgreq) < 0) { diff --git a/usr.sbin/pim6dd/main.c b/usr.sbin/pim6dd/main.c index 54023a9608c4b..99f7086116664 100644 --- a/usr.sbin/pim6dd/main.c +++ b/usr.sbin/pim6dd/main.c @@ -10,15 +10,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -30,22 +30,22 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * - * $Id: main.c,v 1.2 1999/08/13 09:20:13 jinmei Exp $ + * $Id: main.c,v 1.3 2000/03/26 19:11:41 sumikawa Exp $ */ /* * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * @@ -70,17 +70,17 @@ int haveterminal = 1; char *progname; static int sighandled = 0; -#define GOT_SIGINT 0x01 -#define GOT_SIGHUP 0x02 -#define GOT_SIGUSR1 0x04 -#define GOT_SIGUSR2 0x08 -#define GOT_SIGALRM 0x10 +#define GOT_SIGINT 0x01 +#define GOT_SIGHUP 0x02 +#define GOT_SIGUSR1 0x04 +#define GOT_SIGUSR2 0x08 +#define GOT_SIGALRM 0x10 #ifdef SNMP -#define NHANDLERS 34 +#define NHANDLERS 34 #else -#define NHANDLERS 3 +#define NHANDLERS 3 #endif static struct ihandler { @@ -186,10 +186,10 @@ register_input_handler(fd, func) { if (nhandlers >= NHANDLERS) return -1; - + ihandlers[nhandlers].fd = fd; ihandlers[nhandlers++].func = func; - + return 0; } @@ -197,7 +197,7 @@ int main(argc, argv) int argc; char *argv[]; -{ +{ int dummy, dummysigalrm; FILE *fp; struct timeval tv, difftime, curtime, lasttime, *timeout; @@ -209,29 +209,29 @@ main(argc, argv) char c; int tmpd; - + setlinebuf(stderr); - + if (geteuid() != 0) { fprintf(stderr, "pim6dd: must be root\n"); exit(1); } - + progname = strrchr(argv[0], '/'); if (progname) progname++; else progname = argv[0]; - + argv++; argc--; while (argc > 0 && *argv[0] == '-') { if (strcmp(*argv, "-d") == 0) { - if (argc > 1 && *(argv + 1)[0] != '-') { + if (argc > 1 && *(argv + 1)[0] != '-') { char *p,*q; int i, len; struct debugname *d; - + argv++; argc--; debug = 0; @@ -298,7 +298,7 @@ main(argc, argv) usage: tmpd = 0xffffffff; fprintf(stderr, "usage: pim6dd [-c configfile] [-d [debug_level][,debug_level]]\n"); - + fprintf(stderr, "debug levels: "); c = '('; for (d = debugnames; d < debugnames + @@ -311,8 +311,8 @@ main(argc, argv) } fprintf(stderr, ")\n"); exit(1); - } - + } + if (debug != 0) { tmpd = debug; fprintf(stderr, "debug level 0x%lx ", debug); @@ -327,7 +327,7 @@ main(argc, argv) } fprintf(stderr, ")\n"); } - + #ifdef LOG_DAEMON (void)openlog("pim6dd", LOG_PID, LOG_DAEMON); (void)setlogmask(LOG_UPTO(LOG_NOTICE)); @@ -335,9 +335,9 @@ main(argc, argv) (void)openlog("pim6dd", LOG_PID); #endif /* LOG_DAEMON */ sprintf(versionstring, "pim6dd version %s", todaysversion); - + log(LOG_DEBUG, 0, "%s starting", versionstring); - + /* TODO: XXX: use a combination of time and hostid to initialize the random * generator. */ @@ -350,14 +350,14 @@ main(argc, argv) srandom(tm.tv_usec + gethostid()); } #endif - + callout_init(); /* Start up the log rate-limiter */ resetlogging(NULL); init_mld6(); -#if 0 +#if 0 k_stop_pim(mld6_socket); exit(0); /* XXX */ #endif @@ -365,15 +365,15 @@ main(argc, argv) init_pim6_mrt(); init_timers(); - + /* TODO: check the kernel DVMRP/MROUTED/PIM support version */ - + #ifdef SNMP if (i = snmp_init()) return i; #endif /* SNMP */ init_vifs(); - + #ifdef RSRR rsrr_init(); #endif /* RSRR */ @@ -387,7 +387,7 @@ main(argc, argv) sigaction(SIGINT, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); - + FD_ZERO(&readers); FD_SET(mld6_socket, &readers); nfds = mld6_socket + 1; @@ -396,21 +396,21 @@ main(argc, argv) if (ihandlers[i].fd >= nfds) nfds = ihandlers[i].fd + 1; } - + IF_DEBUG(DEBUG_IF) dump_vifs(stderr); IF_DEBUG(DEBUG_PIM_MRT) dump_pim_mrt(stderr); - + /* schedule first timer interrupt */ timer_setTimer(TIMER_INTERVAL, timer, NULL); - + if (debug == 0) { /* Detach from the terminal */ #ifdef TIOCNOTTY int t; #endif /* TIOCNOTTY */ - + haveterminal = 0; if (fork()) exit(0); @@ -422,7 +422,7 @@ main(argc, argv) (void)dup2(0, 2); #if defined(SYSV) || defined(linux) (void)setpgrp(); -#else +#else #ifdef TIOCNOTTY t = open("/dev/tty", 2); if (t >= 0) { @@ -439,13 +439,13 @@ main(argc, argv) #ifdef HAVE_ROUTING_SOCKETS init_routesock(); #endif /* HAVE_ROUTING_SOCKETS */ - + fp = fopen(pidfilename, "w"); if (fp != NULL) { fprintf(fp, "%d\n", (int)getpid()); (void) fclose(fp); } - + /* * Main receive loop. */ @@ -464,7 +464,7 @@ main(argc, argv) timeout->tv_sec = secs; timeout->tv_usec = 0; } - + if (sighandled) { if (sighandled & GOT_SIGINT) { sighandled &= ~GOT_SIGINT; @@ -552,7 +552,7 @@ main(argc, argv) } } } - + } /* Main loop */ log(LOG_NOTICE, 0, "%s exiting", versionstring); @@ -584,16 +584,16 @@ u_long virtual_time = 0; * aging interfaces, quering neighbors and members, etc... The granularity * is equal to TIMER_INTERVAL. */ -static void +static void timer(i) void *i; { age_vifs(); /* Timeout neighbors and groups */ age_routes(); /* Timeout routing entries */ - + virtual_time += TIMER_INTERVAL; timer_setTimer(TIMER_INTERVAL, timer, NULL); -} +} /* * Performs all necessary functions to quit gracefully @@ -629,15 +629,15 @@ handler(sig) case SIGTERM: sighandled |= GOT_SIGINT; break; - + case SIGHUP: sighandled |= GOT_SIGHUP; break; - + case SIGUSR1: sighandled |= GOT_SIGUSR1; break; - + case SIGUSR2: sighandled |= GOT_SIGUSR2; break; @@ -657,9 +657,9 @@ restart(i) #ifdef SNMP int s; #endif /* SNMP */ - + log(LOG_NOTICE, 0, "% restart", versionstring); - + /* * reset all the entries */ @@ -674,7 +674,7 @@ restart(i) close(mld6_socket); close(pim6_socket); close(udp_socket); - + /* * start processing again */ @@ -705,7 +705,7 @@ resetlogging(arg) { int nxttime = 60; void *narg = NULL; - + if (arg == NULL && log_nmsgs > LOG_MAX_MSGS) { nxttime = LOG_SHUT_UP; narg = (void *)&log_nmsgs; /* just need some valid void * */ @@ -714,6 +714,6 @@ resetlogging(arg) } else { log_nmsgs = 0; } - + timer_setTimer(nxttime, resetlogging, narg); } diff --git a/usr.sbin/pim6dd/mld6.c b/usr.sbin/pim6dd/mld6.c index 47634336e0614..f3861c269a4d7 100644 --- a/usr.sbin/pim6dd/mld6.c +++ b/usr.sbin/pim6dd/mld6.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -48,7 +48,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -60,10 +60,10 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * - * $Id: mld6.c,v 1.7 2000/01/04 17:17:21 jinmei Exp $ + * $Id: mld6.c,v 1.13 2000/04/12 07:34:38 jinmei Exp $ */ /* * Part of this program has been derived from mrouted. @@ -100,11 +100,12 @@ static struct msghdr sndmh, static struct iovec sndiov[2]; static struct iovec rcviov[2]; static struct sockaddr_in6 from; -static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int))]; +static u_char *rcvcmsgbuf = NULL; +static int rcvcmsglen; + #ifndef USE_RFC2292BIS u_int8_t raopt[IP6OPT_RTALERT_LEN]; -#endif +#endif static char *sndcmsgbuf; static int ctlbuflen = 0; static u_short rtalert_code; @@ -116,8 +117,8 @@ static void accept_mld6 __P((int len)); static void make_mld6_msg __P((int, int, struct sockaddr_in6 *, struct sockaddr_in6 *, struct in6_addr *, int, int, int, int)); -#ifndef IP6OPT_ROUTER_ALERT -#define IP6OPT_ROUTER_ALERT IP6OPT_RTALERT +#ifndef IP6OPT_ROUTER_ALERT /* XXX to be compatible older systems */ +#define IP6OPT_ROUTER_ALERT IP6OPT_RTALERT #endif /* @@ -131,10 +132,15 @@ init_mld6() rtalert_code = htons(IP6OPT_RTALERT_MLD); if (!mld6_recv_buf && (mld6_recv_buf = malloc(RECV_BUF_SIZE)) == NULL) - log(LOG_ERR, 0, "malloca failed"); + log(LOG_ERR, 0, "malloc failed"); if (!mld6_send_buf && (mld6_send_buf = malloc(RECV_BUF_SIZE)) == NULL) - log(LOG_ERR, 0, "malloca failed"); + log(LOG_ERR, 0, "malloc failed"); + rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + if (rcvcmsgbuf == NULL && (rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) + log(LOG_ERR, 0,"malloc failed"); + IF_DEBUG(DEBUG_KERN) log(LOG_DEBUG,0,"%d octets allocated for the emit/recept buffer mld6",RECV_BUF_SIZE); @@ -173,7 +179,7 @@ init_mld6() if (setsockopt(mld6_socket, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on)) < 0) log(LOG_ERR, errno, "setsockopt(IPV6_PKTINFO)"); -#endif +#endif on = 1; /* specify to tell value of hoplimit field of received IP6 hdr */ #ifdef IPV6_RECVHOPLIMIT @@ -184,7 +190,7 @@ init_mld6() if (setsockopt(mld6_socket, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on)) < 0) log(LOG_ERR, errno, "setsockopt(IPV6_HOPLIMIT)"); -#endif +#endif /* initialize msghdr for receiving packets */ rcviov[0].iov_base = (caddr_t) mld6_recv_buf; rcviov[0].iov_len = RECV_BUF_SIZE; @@ -193,7 +199,7 @@ init_mld6() rcvmh.msg_iov = rcviov; rcvmh.msg_iovlen = 1; rcvmh.msg_control = (caddr_t) rcvcmsgbuf; - rcvmh.msg_controllen = sizeof(rcvcmsgbuf); + rcvmh.msg_controllen = rcvcmsglen; /* initialize msghdr for sending packets */ sndiov[0].iov_base = (caddr_t)mld6_send_buf; @@ -205,7 +211,7 @@ init_mld6() raopt[0] = IP6OPT_ROUTER_ALERT; raopt[1] = IP6OPT_RTALERT_LEN - 2; memcpy(&raopt[2], (caddr_t) & rtalert_code, sizeof(u_short)); -#endif +#endif /* register MLD message handler */ if (register_input_handler(mld6_socket, mld6_read) < 0) @@ -250,19 +256,6 @@ int recvlen; int ifindex = 0; struct sockaddr_in6 *src = (struct sockaddr_in6 *) rcvmh.msg_name; - /* - * If control length is zero, it must be an upcall from the kernel - * multicast forwarding engine. - * XXX: can we trust it? - */ - if (rcvmh.msg_controllen == 0) { - /* XXX: msg_controllen must be reset in this case. */ - rcvmh.msg_controllen = sizeof(rcvcmsgbuf); - - process_kernel_call(); - return; - } - if (recvlen < sizeof(struct mld6_hdr)) { log(LOG_WARNING, 0, @@ -271,6 +264,20 @@ int recvlen; return; } mldh = (struct mld6_hdr *) rcvmh.msg_iov[0].iov_base; + + /* + * Packets sent up from kernel to daemon have ICMPv6 type = 0. + * Note that we set filters on the mld6_socket, so we should never + * see a "normal" ICMPv6 packet with type 0 of ICMPv6 type. + */ + if (mldh->mld6_type == 0) { + /* XXX: msg_controllen must be reset in this case. */ + rcvmh.msg_controllen = rcvcmsglen; + + process_kernel_call(); + return; + } + group = &mldh->mld6_addr; /* extract optional information via Advanced API */ @@ -400,7 +407,7 @@ make_mld6_msg(type, code, src, dst, group, ifindex, delay, datalen, alert) datalen = sizeof(struct mld6_hdr); break; } - + bzero(mhp, sizeof(*mhp)); mhp->mld6_type = type; mhp->mld6_code = code; @@ -427,6 +434,7 @@ make_mld6_msg(type, code, src, dst, group, ifindex, delay, datalen, alert) hbhlen = inet6_option_space(sizeof(raopt)); ctllen += hbhlen; #endif + } /* extend ancillary data space (if necessary) */ if (ctlbuflen < ctllen) { @@ -488,7 +496,7 @@ make_mld6_msg(type, code, src, dst, group, ifindex, delay, datalen, alert) if (inet6_option_append(cmsgp, raopt, 4, 0)) log(LOG_ERR, 0, /* assert */ "make_mld6_msg: inet6_option_append failed"); -#endif +#endif cmsgp = CMSG_NXTHDR(&sndmh, cmsgp); } } @@ -508,7 +516,7 @@ send_mld6(type, code, src, dst, group, index, delay, datalen, alert) { int setloop = 0; struct sockaddr_in6 *dstp; - + make_mld6_msg(type, code, src, dst, group, index, delay, datalen, alert); dstp = (struct sockaddr_in6 *)sndmh.msg_name; if (IN6_ARE_ADDR_EQUAL(&dstp->sin6_addr, &allnodes_group.sin6_addr)) { @@ -529,7 +537,7 @@ send_mld6(type, code, src, dst, group, index, delay, datalen, alert) k_set_loop(mld6_socket, FALSE); return; } - + IF_DEBUG(DEBUG_PKT|debug_kind(IPPROTO_IGMP, type, 0)) log(LOG_DEBUG, 0, "SENT %s from %-15s to %s", packet_kind(IPPROTO_ICMPV6, type, 0), diff --git a/usr.sbin/pim6dd/mld6.h b/usr.sbin/pim6dd/mld6.h index 21453a3bacde7..310ebcf09bc1a 100644 --- a/usr.sbin/pim6dd/mld6.h +++ b/usr.sbin/pim6dd/mld6.h @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -32,14 +32,17 @@ /* * Constans for Multicast Listener Discovery protocol for IPv6. */ -#define MLD6_ROBUSTNESS_VARIABLE 2 -#define MLD6_QUERY_INTERVAL 125 /* in seconds */ -#define MLD6_QUERY_RESPONSE_INTERVAL 10000 /* in milliseconds */ +#define MLD6_ROBUSTNESS_VARIABLE 2 +#define MLD6_QUERY_INTERVAL 125 /* in seconds */ +#define MLD6_QUERY_RESPONSE_INTERVAL 10000 /* in milliseconds */ #ifndef MLD6_TIMER_SCALE -#define MLD6_TIMER_SCALE 1000 -#endif -#define MLD6_LISTENER_INTERVAL (MLD6_ROBUSTNESS_VARIABLE * \ +#define MLD6_TIMER_SCALE 1000 +#endif +#define MLD6_LISTENER_INTERVAL (MLD6_ROBUSTNESS_VARIABLE * \ MLD6_QUERY_INTERVAL + \ MLD6_QUERY_RESPONSE_INTERVAL / MLD6_TIMER_SCALE) #define MLD6_LAST_LISTENER_QUERY_INTERVAL 1000 /* in milliseconds */ #define MLD6_LAST_LISTENER_QUERY_COUNT MLD6_ROBUSTNESS_VARIABLE +#define MLD6_OTHER_QUERIER_PRESENT_INTERVAL (MLD6_ROBUSTNESS_VARIABLE * \ + MLD6_QUERY_INTERVAL + \ + MLD6_QUERY_RESPONSE_INTERVAL / (2 * MLD6_TIMER_SCALE)) diff --git a/usr.sbin/pim6dd/mld6_proto.c b/usr.sbin/pim6dd/mld6_proto.c index 97cbea1b335a3..26d8952e7b3ec 100644 --- a/usr.sbin/pim6dd/mld6_proto.c +++ b/usr.sbin/pim6dd/mld6_proto.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -39,15 +39,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -59,22 +59,22 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * - * $Id: mld6_proto.c,v 1.2 1999/09/12 17:00:09 jinmei Exp $ + * $Id: mld6_proto.c,v 1.4 2000/05/05 12:38:30 jinmei Exp $ */ /* * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * @@ -110,7 +110,7 @@ query_groups(v) register struct uvif *v; { register struct listaddr *g; - + v->uv_gq_timer = MLD6_QUERY_INTERVAL; if (v->uv_flags & VIFF_QUERIER && (v->uv_flags & VIFF_NOLISTENER) == 0) send_mld6(MLD6_LISTENER_QUERY, 0, &v->uv_linklocal->pa_addr, @@ -155,7 +155,7 @@ accept_listener_query(src, dst, group, tmo) v = &uvifs[mifi]; - if (v->uv_querier == NULL || inet6_equal(&v->uv_querier->al_addr, src)) + if (v->uv_querier == NULL || !inet6_equal(&v->uv_querier->al_addr, src)) { /* * This might be: @@ -177,29 +177,20 @@ accept_listener_query(src, dst, group, tmo) if (!v->uv_querier) { v->uv_querier = (struct listaddr *) malloc(sizeof(struct listaddr)); - v->uv_querier->al_next = (struct listaddr *)NULL; - v->uv_querier->al_timer = 0; - v->uv_querier->al_genid = 0; - v->uv_querier->al_pv = 0; - v->uv_querier->al_mv = 0; - v->uv_querier->al_old = 0; - v->uv_querier->al_index = 0; - v->uv_querier->al_timerid = 0; - v->uv_querier->al_query = 0; - v->uv_querier->al_flags = 0; - - v->uv_flags &= ~VIFF_QUERIER; + memset(v->uv_querier, 0, + sizeof(struct listaddr)); } + v->uv_flags &= ~VIFF_QUERIER; v->uv_querier->al_addr = *src; time(&v->uv_querier->al_ctime); } } - + /* * Reset the timer since we've received a query. */ if (v->uv_querier && inet6_equal(src, &v->uv_querier->al_addr)) - v->uv_querier->al_timer = 0; + v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL; /* * If this is a Group-Specific query which we did not source, @@ -273,7 +264,7 @@ accept_listener_report(src, dst, group) "accept_listener_report: can't find a mif"); return; } - + IF_DEBUG(DEBUG_MLD) log(LOG_INFO, 0, "accepting multicast listener report: " @@ -282,7 +273,7 @@ accept_listener_report(src, dst, group) inet6_fmt(group)); v = &uvifs[mifi]; - + /* * Look for the group in our group list; if found, reset its timer. */ @@ -354,7 +345,7 @@ accept_listener_done(src, dst, group) inet6_fmt(dst), inet6_fmt(group)); v = &uvifs[mifi]; - + if (!(v->uv_flags & (VIFF_QUERIER | VIFF_DR))) return; @@ -377,14 +368,14 @@ accept_listener_done(src, dst, group) */ if (g->al_old) return; - + /* * still waiting for a reply to a query, * ignore the done */ if (g->al_query) return; - + /** delete old timer set a timer for expiration **/ if (g->al_timerid) g->al_timerid = DeleteTimer(g->al_timerid); @@ -453,7 +444,7 @@ SetTimer(mifi, g) struct listaddr *g; { cbk_t *cbk; - + cbk = (cbk_t *) malloc(sizeof(cbk_t)); cbk->mifi = mifi; cbk->g = g; @@ -525,7 +516,7 @@ check_multicast_listener(v, group) * Look for the group in our listener list; */ for (g = v->uv_groups; g != NULL; g = g->al_next) { - if (inet6_equal(group, &g->al_addr)) + if (inet6_equal(group, &g->al_addr)) return TRUE; } return FALSE; diff --git a/usr.sbin/pim6dd/mrt.c b/usr.sbin/pim6dd/mrt.c index 13d5149a142e5..df4df3cf7afc6 100644 --- a/usr.sbin/pim6dd/mrt.c +++ b/usr.sbin/pim6dd/mrt.c @@ -10,15 +10,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -30,22 +30,22 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * - * $Id: mrt.c,v 1.2 1999/08/24 10:04:56 jinmei Exp $ + * $Id: mrt.c,v 1.3 2000/05/18 16:09:39 itojun Exp $ */ /* * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * @@ -85,7 +85,7 @@ static mrtentry_t *create_mrtentry __P((srcentry_t *srcentry_ptr, u_int16 flags)); -void +void init_pim6_mrt() { @@ -106,7 +106,7 @@ init_pim6_mrt() srclist->metric = 0; srclist->preference = 0; srclist->timer = 0; - + /* Initialize the group list */ /* The first entry has the unspecified address and is not used */ /* The order is the smallest address first. */ @@ -128,7 +128,7 @@ find_group(group) if (!IN6_IS_ADDR_MULTICAST(&group->sin6_addr)) return (grpentry_t *)NULL; - + if (search_grplist(group, &grpentry_ptr) == TRUE) { /* Group found! */ return (grpentry_ptr); @@ -145,7 +145,7 @@ find_source(source) if (!inet6_valid_host(source)) return (srcentry_t *)NULL; - + if (search_srclist(source, &srcentry_ptr) == TRUE) { /* Source found! */ return (srcentry_ptr); @@ -166,12 +166,12 @@ find_route(source, group, flags, create) if (!IN6_IS_ADDR_MULTICAST(&group->sin6_addr)) return (mrtentry_t *)NULL; - + if (!inet6_valid_host(source)) return (mrtentry_t *)NULL; - + if (create == DONT_CREATE) { - if (search_grplist(group, &grpentry_ptr) == FALSE) + if (search_grplist(group, &grpentry_ptr) == FALSE) return (mrtentry_t *)NULL; /* Search for the source */ if (search_grpmrtlink(grpentry_ptr, source, @@ -212,11 +212,11 @@ find_route(source, group, flags, create) } return (mrtentry_t *)NULL; } - + if (mrtentry_ptr->flags & MRTF_NEW) { struct mrtfilter *f; - /* The mrtentry pref/metric should be the pref/metric of the - * _upstream_ assert winner. Since this isn't known now, + /* The mrtentry pref/metric should be the pref/metric of the + * _upstream_ assert winner. Since this isn't known now, * set it to the config'ed default */ mrtentry_ptr->incoming = srcentry_ptr->incoming; @@ -227,7 +227,7 @@ find_route(source, group, flags, create) if ((f = search_filter(&group->sin6_addr))) IF_COPY(&f->ifset, &mrtentry_ptr->filter_oifs); } - + return (mrtentry_ptr); } @@ -245,7 +245,7 @@ delete_srcentry(srcentry_ptr) srcentry_ptr->prev->next = srcentry_ptr->next; if (srcentry_ptr->next != (srcentry_t *)NULL) srcentry_ptr->next->prev = srcentry_ptr->prev; - + for (mrtentry_ptr = srcentry_ptr->mrtlink; mrtentry_ptr != (mrtentry_t *)NULL; mrtentry_ptr = mrtentry_next) { @@ -273,14 +273,14 @@ delete_grpentry(grpentry_ptr) { mrtentry_t *mrtentry_ptr; mrtentry_t *mrtentry_next; - + if (grpentry_ptr == (grpentry_t *)NULL) return; /* TODO: XXX: the first entry is unused and always there */ grpentry_ptr->prev->next = grpentry_ptr->next; if (grpentry_ptr->next != (grpentry_t *)NULL) grpentry_ptr->next->prev = grpentry_ptr->prev; - + for (mrtentry_ptr = grpentry_ptr->mrtlink; mrtentry_ptr != (mrtentry_t *)NULL; mrtentry_ptr = mrtentry_next) { @@ -329,10 +329,10 @@ delete_mrtentry(mrtentry_ptr) delete_grpentry(mrtentry_ptr->group); } } - + if (mrtentry_ptr->grpnext != (mrtentry_t *)NULL) mrtentry_ptr->grpnext->grpprev = mrtentry_ptr->grpprev; - + /* Delete from the srcentry MRT chain */ if (mrtentry_ptr->srcprev != (mrtentry_t *)NULL) mrtentry_ptr->srcprev->srcnext = mrtentry_ptr->srcnext; @@ -356,7 +356,7 @@ search_srclist(source, sourceEntry) register srcentry_t **sourceEntry; { register srcentry_t *s_prev,*s; - + for (s_prev = srclist, s = s_prev->next; s != (srcentry_t *)NULL; s_prev = s, s = s->next) { /* The srclist is ordered with the smallest addresses first. @@ -368,7 +368,7 @@ search_srclist(source, sourceEntry) *sourceEntry = s; return(TRUE); } - break; + break; } *sourceEntry = s_prev; /* The insertion point is between s_prev and s */ return(FALSE); @@ -381,7 +381,7 @@ search_grplist(group, groupEntry) register grpentry_t **groupEntry; { register grpentry_t *g_prev, *g; - + for (g_prev = grplist, g = g_prev->next; g != (grpentry_t *)NULL; g_prev = g, g = g->next) { /* The grplist is ordered with the smallest address first. @@ -408,7 +408,7 @@ create_srcentry(source) if (search_srclist(source, &srcentry_prev) == TRUE) return (srcentry_prev); - + srcentry_ptr = (srcentry_t *)malloc(sizeof(srcentry_t)); if (srcentry_ptr == (srcentry_t *)NULL) { log(LOG_WARNING, 0, "Memory allocation error for srcentry %s", @@ -420,7 +420,7 @@ create_srcentry(source) /* * Free the memory if there is error getting the iif and * the next hop (upstream) router. - */ + */ if (set_incoming(srcentry_ptr, PIM_IIF_SOURCE) == FALSE) { free((char *)srcentry_ptr); return (srcentry_t *)NULL; @@ -432,7 +432,7 @@ create_srcentry(source) srcentry_ptr->prev = srcentry_prev; if (srcentry_ptr->next != (srcentry_t *)NULL) srcentry_ptr->next->prev = srcentry_ptr; - + IF_DEBUG(DEBUG_MFC) log(LOG_DEBUG, 0, "create source entry, source %s", inet6_fmt(&source->sin6_addr)); @@ -449,7 +449,7 @@ create_grpentry(group) if (search_grplist(group, &grpentry_prev) == TRUE) return (grpentry_prev); - + grpentry_ptr = (grpentry_t *)malloc(sizeof(grpentry_t)); if (grpentry_ptr == (grpentry_t *)NULL) { log(LOG_WARNING, 0, "Memory allocation error for grpentry %s", @@ -466,7 +466,7 @@ create_grpentry(group) grpentry_ptr->prev = grpentry_prev; if (grpentry_ptr->next != (grpentry_t *)NULL) grpentry_ptr->next->prev = grpentry_ptr; - + IF_DEBUG(DEBUG_MFC) log(LOG_DEBUG, 0, "create group entry, group %s", inet6_fmt(&group->sin6_addr)); @@ -476,18 +476,18 @@ create_grpentry(group) /* * Return TRUE if the entry is found and then *mrtPtr is set to point to that - * entry. Otherwise return FALSE and *mrtPtr points the the previous entry + * entry. Otherwise return FALSE and *mrtPtr points the previous entry * (or NULL if first in the chain. */ static int search_srcmrtlink(srcentry_ptr, group, mrtPtr) - srcentry_t *srcentry_ptr; + srcentry_t *srcentry_ptr; struct sockaddr_in6 *group; mrtentry_t **mrtPtr; { register mrtentry_t *mrtentry_ptr; register mrtentry_t *m_prev = (mrtentry_t *)NULL; - + for(mrtentry_ptr = srcentry_ptr->mrtlink; mrtentry_ptr != (mrtentry_t *)NULL; m_prev = mrtentry_ptr, mrtentry_ptr = mrtentry_ptr->srcnext) { @@ -509,7 +509,7 @@ search_srcmrtlink(srcentry_ptr, group, mrtPtr) /* * Return TRUE if the entry is found and then *mrtPtr is set to point to that - * entry. Otherwise return FALSE and *mrtPtr points the the previous entry + * entry. Otherwise return FALSE and *mrtPtr points the previous entry * (or NULL if first in the chain. */ static int @@ -520,7 +520,7 @@ search_grpmrtlink(grpentry_ptr, source, mrtPtr) { register mrtentry_t *mrtentry_ptr; register mrtentry_t *m_prev = (mrtentry_t *)NULL; - + for (mrtentry_ptr = grpentry_ptr->mrtlink; mrtentry_ptr != (mrtentry_t *)NULL; m_prev = mrtentry_ptr, mrtentry_ptr = mrtentry_ptr->grpnext) { @@ -595,13 +595,13 @@ alloc_mrtentry(srcentry_ptr, grpentry_ptr) u_int16 i, *i_ptr; u_long *il_ptr; u_int8 vif_numbers; - + mrtentry_ptr = (mrtentry_t *)malloc(sizeof(mrtentry_t)); if (mrtentry_ptr == (mrtentry_t *)NULL) { log(LOG_WARNING, 0, "alloc_mrtentry(): out of memory"); return (mrtentry_t *)NULL; } - + /* * grpnext, grpprev, srcnext, srcprev will be setup when we link the * mrtentry to the source and group chains @@ -631,7 +631,7 @@ alloc_mrtentry(srcentry_ptr, grpentry_ptr) */ #ifdef SAVE_MEMORY mrtentry_ptr->prune_timers = (u_int16 *)malloc(sizeof(u_int16) * numvifs); - mrtentry_ptr->prune_delay_timerids = + mrtentry_ptr->prune_delay_timerids = (u_long *)malloc(sizeof(u_long) * numvifs); mrtentry_ptr->last_assert = (u_long *)malloc(sizeof(u_long) * numvifs); mrtentry_ptr->last_prune = (u_long *)malloc(sizeof(u_long) * numvifs); @@ -693,7 +693,7 @@ create_mrtentry(srcentry_ptr, grpentry_ptr, flags) /* (S,G) entry */ source = &srcentry_ptr->address; group = &grpentry_ptr->group; - + if (search_grpmrtlink(grpentry_ptr, source, &r_grp_insert) == TRUE) { return(r_grp_insert); } @@ -715,7 +715,7 @@ create_mrtentry(srcentry_ptr, grpentry_ptr, flags) return (mrtentry_t *)NULL; /* * r_new has to be insert right after r_grp_insert in the - * grp mrtlink chain and right after r_src_insert in the + * grp mrtlink chain and right after r_src_insert in the * src mrtlink chain */ insert_grpmrtlink(r_new, r_grp_insert, grpentry_ptr); @@ -761,7 +761,7 @@ search_filter(maddr) /* * Make a new filter entry. - * This function assumes + * This function assumes */ struct mrtfilter * add_filter(type, maddr1, maddr2, plen) diff --git a/usr.sbin/pim6dd/mrt.h b/usr.sbin/pim6dd/mrt.h index 156476d909af7..daac17088c566 100644 --- a/usr.sbin/pim6dd/mrt.h +++ b/usr.sbin/pim6dd/mrt.h @@ -10,15 +10,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -30,7 +30,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * * $Id: mrt.h,v 1.2 1999/08/24 10:04:56 jinmei Exp $ @@ -39,34 +39,34 @@ * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * * $FreeBSD$ */ -#define MRTF_SPT 0x0001 /* iif toward source */ -#define MRTF_WC 0x0002 /* (*,G) entry */ -#define MRTF_RP 0x0004 /* iif toward RP */ -#define MRTF_NEW 0x0008 /* new created routing entry */ -#define MRTF_IIF_REGISTER 0x0020 /* ??? */ -#define MRTF_REGISTER 0x0080 /* ??? */ -#define MRTF_KERNEL_CACHE 0x0200 /* a mirror for the kernel cache */ -#define MRTF_NULL_OIF 0x0400 /* null oif cache.. ??? */ -#define MRTF_REG_SUPP 0x0800 /* register suppress ??? */ -#define MRTF_ASSERTED 0x1000 /* upstream is not that of src ??? */ -#define MRTF_SG 0x2000 /* (S,G) pure, not hanging off of (*,G)*/ -#define MRTF_PMBR 0x4000 /* (*,*,RP) entry (for interop) */ +#define MRTF_SPT 0x0001 /* iif toward source */ +#define MRTF_WC 0x0002 /* (*,G) entry */ +#define MRTF_RP 0x0004 /* iif toward RP */ +#define MRTF_NEW 0x0008 /* new created routing entry */ +#define MRTF_IIF_REGISTER 0x0020 /* ??? */ +#define MRTF_REGISTER 0x0080 /* ??? */ +#define MRTF_KERNEL_CACHE 0x0200 /* a mirror for the kernel cache */ +#define MRTF_NULL_OIF 0x0400 /* null oif cache.. ??? */ +#define MRTF_REG_SUPP 0x0800 /* register suppress ??? */ +#define MRTF_ASSERTED 0x1000 /* upstream is not that of src ??? */ +#define MRTF_SG 0x2000 /* (S,G) pure, not hanging off of (*,G)*/ +#define MRTF_PMBR 0x4000 /* (*,*,RP) entry (for interop) */ /* Macro to duplicate oif info (oif bits, timers): XXX: unused */ -#define VOIF_COPY(from, to) \ +#define VOIF_COPY(from, to) \ do { \ VIFM_COPY((from)->joined_oifs, (to)->joined_oifs); \ VIFM_COPY((from)->oifs, (to)->oifs); \ @@ -81,7 +81,7 @@ } while (0) #ifdef SAVE_MEMORY -#define FREE_MRTENTRY(mrtentry_ptr) \ +#define FREE_MRTENTRY(mrtentry_ptr) \ do { \ u_int16 i; \ u_long *il_ptr; \ @@ -95,7 +95,7 @@ free((char *)(mrtentry_ptr)); \ } while (0) #else -#define FREE_MRTENTRY(mrtentry_ptr) \ +#define FREE_MRTENTRY(mrtentry_ptr) \ do { \ u_int16 i; \ u_long *il_ptr; \ @@ -201,12 +201,12 @@ struct mrtentry { struct vif_count { u_long icount; /* Input packet count on vif */ u_long ocount; /* Output packet count on vif */ - u_long ibytes; /* Input byte count on vif */ - u_long obytes; /* Output byte count on vif */ + u_long ibytes; /* Input byte count on vif */ + u_long obytes; /* Output byte count on vif */ }; -#define FILTER_RANGE 0 -#define FILTER_PREFIX 1 +#define FILTER_RANGE 0 +#define FILTER_PREFIX 1 struct mrtfilter { struct mrtfilter *next; /* link to the next entry */ int type; /* filter type: RANGE or PREFIX */ @@ -222,7 +222,7 @@ struct mrtfilter { } mrtu; if_set ifset; /* interface list */ }; -#define mrtf_from mrtu.mrtfu_range.from -#define mrtf_to mrtu.mrtfu_range.to -#define mrtf_prefix mrtu.mrtfu_prefix.prefix -#define mrtf_mask mrtu.mrtfu_prefix.mask +#define mrtf_from mrtu.mrtfu_range.from +#define mrtf_to mrtu.mrtfu_range.to +#define mrtf_prefix mrtu.mrtfu_prefix.prefix +#define mrtf_mask mrtu.mrtfu_prefix.mask diff --git a/usr.sbin/pim6dd/pathnames.h b/usr.sbin/pim6dd/pathnames.h index ff7c9ef4940ad..b611736774929 100644 --- a/usr.sbin/pim6dd/pathnames.h +++ b/usr.sbin/pim6dd/pathnames.h @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,7 +31,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: pathnames.h,v 1.2 1999/12/16 05:36:37 jinmei Exp $ @@ -48,16 +48,16 @@ */ -#define _PATH_PIM6D_CONF "/etc/pim6dd.conf" +#define _PATH_PIM6D_CONF "/etc/pim6dd.conf" #if (defined(BSD) && (BSD >= 199103)) -#define _PATH_PIM6D_PID "/var/run/pim6dd.pid" -#define _PATH_PIM6D_GENID "/var/run/pim6dd.genid" -#define _PATH_PIM6D_DUMP "/var/run/pim6dd.dump" -#define _PATH_PIM6D_CACHE "/var/run/pim6dd.cache" +#define _PATH_PIM6D_PID "/var/run/pim6dd.pid" +#define _PATH_PIM6D_GENID "/var/run/pim6dd.genid" +#define _PATH_PIM6D_DUMP "/var/run/pim6dd.dump" +#define _PATH_PIM6D_CACHE "/var/run/pim6dd.cache" #else -#define _PATH_PIM6D_PID "/etc/pim6dd.pid" -#define _PATH_PIM6D_GENID "/etc/pim6dd.genid" -#define _PATH_PIM6D_DUMP "/etc/pim6dd.dump" -#define _PATH_PIM6D_CACHE "/etc/pim6dd.cache" +#define _PATH_PIM6D_PID "/etc/pim6dd.pid" +#define _PATH_PIM6D_GENID "/etc/pim6dd.genid" +#define _PATH_PIM6D_DUMP "/etc/pim6dd.dump" +#define _PATH_PIM6D_CACHE "/etc/pim6dd.cache" #endif diff --git a/usr.sbin/pim6dd/pim6.c b/usr.sbin/pim6dd/pim6.c index f15d6b181aa2c..e0a18fe309af1 100644 --- a/usr.sbin/pim6dd/pim6.c +++ b/usr.sbin/pim6dd/pim6.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -47,7 +47,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -59,10 +59,10 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * - * $Id: pim6.c,v 1.3 1999/10/26 08:39:19 itojun Exp $ + * $Id: pim6.c,v 1.6 2000/03/07 02:23:50 jinmei Exp $ * $FreeBSD$ */ @@ -79,12 +79,13 @@ struct sockaddr_in6 allpim6routers_group; /* ALL_PIM_ROUTERS group */ int pim6_socket; /* socket for PIM control msgs */ /* - * Local variables. + * Local variables. */ static struct sockaddr_in6 from; static struct msghdr sndmh; static struct iovec sndiov[2]; static struct in6_pktinfo *sndpktinfo; +static u_char *sndcmsgbuf = NULL; /* * Local function definitions. @@ -92,15 +93,16 @@ static struct in6_pktinfo *sndpktinfo; static void pim6_read __P((int f, fd_set *rfd)); static void accept_pim6 __P((int recvlen)); static int pim6_cksum __P((u_short *, struct in6_addr *, - struct in6_addr *, int)); + struct in6_addr *, int)); void init_pim6() { - static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + static int sndcmsglen; struct cmsghdr *cmsgp = (struct cmsghdr *)sndcmsgbuf; - if ((pim6_socket = socket(AF_INET6, SOCK_RAW, IPPROTO_PIM)) < 0) + sndcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)); + if ((pim6_socket = socket(AF_INET6, SOCK_RAW, IPPROTO_PIM)) < 0) log(LOG_ERR, errno, "PIM6 socket"); k_set_rcvbuf(pim6_socket, SO_RECV_BUF_SIZE_MAX, @@ -113,7 +115,7 @@ init_pim6() if (inet_pton(AF_INET6, "ff02::d", (void *)&allpim6routers_group.sin6_addr) != 1) log(LOG_ERR, 0, "inet_pton failed for ff02::d"); - + if ((pim6_recv_buf = malloc(RECV_BUF_SIZE)) == NULL || (pim6_send_buf = malloc(RECV_BUF_SIZE)) == NULL) { log(LOG_ERR, 0, "init_pim6: malloc failed\n"); @@ -123,13 +125,16 @@ init_pim6() sndmh.msg_namelen = sizeof(struct sockaddr_in6); sndmh.msg_iov = sndiov; sndmh.msg_iovlen = 1; + if (sndcmsgbuf == NULL && (sndcmsgbuf = malloc(sndcmsglen)) == NULL) + log(LOG_ERR, 0, "malloc failed"); sndmh.msg_control = (caddr_t)sndcmsgbuf; - sndmh.msg_controllen = sizeof(sndcmsgbuf); + sndmh.msg_controllen = sndcmsglen; /* initilization cmsg for specifing outgoing interfaces and source */ - sndpktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsgp); + cmsgp=(struct cmsghdr *)sndcmsgbuf; cmsgp->cmsg_len = CMSG_SPACE(sizeof(struct in6_pktinfo)); cmsgp->cmsg_level = IPPROTO_IPV6; cmsgp->cmsg_type = IPV6_PKTINFO; + sndpktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsgp); if (register_input_handler(pim6_socket, pim6_read) < 0) log(LOG_ERR, 0, @@ -170,9 +175,9 @@ pim6_read(f, rfd) /* Use of omask taken from main() */ omask = sigblock(sigmask(SIGALRM)); #endif /* SYSV */ - + accept_pim6(pim6_recvlen); - + #ifdef SYSV (void)sigprocmask(SIG_SETMASK, &oblock, (sigset_t *)NULL); #else @@ -191,7 +196,7 @@ accept_pim6(pimlen) /* sanity check */ if (pimlen < sizeof(pim)) { log(LOG_WARNING, 0, - "data field too short (%u bytes) for PIM header, from %s", + "data field too short (%u bytes) for PIM header, from %s", pimlen, inet6_fmt(&src->sin6_addr)); return; } @@ -201,7 +206,7 @@ accept_pim6(pimlen) IF_DEBUG(DEBUG_PIM_DETAIL) { IF_DEBUG(DEBUG_PIM) { log(LOG_DEBUG, 0, "Receiving %s from %s", - packet_kind(IPPROTO_PIM, pim->pim_type, 0), + packet_kind(IPPROTO_PIM, pim->pim_type, 0), inet6_fmt(&src->sin6_addr)); log(LOG_DEBUG, 0, "PIM type is %u", pim->pim_type); } @@ -218,7 +223,7 @@ accept_pim6(pimlen) switch (pim->pim_type) { case PIM_HELLO: - receive_pim6_hello(src, (char *)(pim), pimlen); + receive_pim6_hello(src, (char *)(pim), pimlen); break; case PIM_REGISTER: log(LOG_INFO, 0, "ignore %s from %s", @@ -231,7 +236,7 @@ accept_pim6(pimlen) inet6_fmt(&src->sin6_addr)); break; case PIM_JOIN_PRUNE: - receive_pim6_join_prune(src, (char *)(pim), pimlen); + receive_pim6_join_prune(src, (char *)(pim), pimlen); break; case PIM_BOOTSTRAP: log(LOG_INFO, 0, "ignore %s from %s", @@ -239,7 +244,7 @@ accept_pim6(pimlen) inet6_fmt(&src->sin6_addr)); break; case PIM_ASSERT: - receive_pim6_assert(src, (char *)(pim), pimlen); + receive_pim6_assert(src, (char *)(pim), pimlen); break; case PIM_GRAFT: case PIM_GRAFT_ACK: @@ -264,7 +269,7 @@ accept_pim6(pimlen) * Send a multicast PIM packet from src to dst, PIM message type = "type" * and data length (after the PIM header) = "datalen" */ -void +void send_pim6(buf, src, dst, type, datalen) char *buf; struct sockaddr_in6 *src, *dst; @@ -312,7 +317,7 @@ send_pim6(buf, src, dst, type, datalen) IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &allpim6routers_group.sin6_addr)) { setloop = 1; - k_set_loop(pim6_socket, TRUE); + k_set_loop(pim6_socket, TRUE); } } @@ -327,12 +332,12 @@ send_pim6(buf, src, dst, type, datalen) inet6_fmt(&src->sin6_addr), inet6_fmt(&dst->sin6_addr)); if (setloop) - k_set_loop(pim6_socket, FALSE); + k_set_loop(pim6_socket, FALSE); return; } if (setloop) - k_set_loop(pim6_socket, FALSE); + k_set_loop(pim6_socket, FALSE); IF_DEBUG(DEBUG_PIM_DETAIL) { IF_DEBUG(DEBUG_PIM) { @@ -348,7 +353,7 @@ send_pim6(buf, src, dst, type, datalen) } u_int pim_send_cnt = 0; -#define SEND_DEBUG_NUMBER 50 +#define SEND_DEBUG_NUMBER 50 /* ============================== */ @@ -359,8 +364,8 @@ u_int pim_send_cnt = 0; * code and should be modified for each CPU to be as fast as possible. */ -#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) -#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} +#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) +#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} static union { u_short phs[4]; diff --git a/usr.sbin/pim6dd/pim6_proto.c b/usr.sbin/pim6dd/pim6_proto.c index 2be8f5ccb4981..f4460ba15e0c5 100644 --- a/usr.sbin/pim6dd/pim6_proto.c +++ b/usr.sbin/pim6dd/pim6_proto.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -38,15 +38,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -58,22 +58,22 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * - * $Id: pim6_proto.c,v 1.4 1999/10/27 11:40:30 jinmei Exp $ + * $Id: pim6_proto.c,v 1.5 2000/04/30 10:50:31 jinmei Exp $ */ /* * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * @@ -145,7 +145,7 @@ receive_pim6_hello(src, pim_message, datalen) IF_DEBUG(DEBUG_PIM_HELLO | DEBUG_PIM_TIMER) log(LOG_DEBUG, 0, "PIM HELLO holdtime from %s is %u", inet6_fmt(&src->sin6_addr), holdtime); - + for (prev_nbr = (pim_nbr_entry_t *)NULL, nbr = v->uv_pim_neighbors; nbr != (pim_nbr_entry_t *)NULL; prev_nbr = nbr, nbr = nbr->next) { @@ -210,7 +210,6 @@ receive_pim6_hello(src, pim_message, datalen) * DR address and it wins (is >) over the local address. */ v->uv_flags &= ~VIFF_DR; - v->uv_flags &= ~VIFF_QUERIER; } /* @@ -236,7 +235,7 @@ receive_pim6_hello(src, pim_message, datalen) mrtentry_ptr = mrtentry_ptr->srcnext) { if(!(IF_ISSET(mifi, &mrtentry_ptr->oifs))) { - state_change = + state_change = change_interfaces(mrtentry_ptr, srcentry_ptr->incoming, &mrtentry_ptr->pruned_oifs, @@ -247,7 +246,7 @@ receive_pim6_hello(src, pim_message, datalen) } } } - + IF_DEBUG(DEBUG_PIM_HELLO) dump_vifs(stderr); /* Show we got a new neighbor */ return(TRUE); @@ -264,7 +263,7 @@ delete_pim6_nbr(nbr_delete) int state_change; v = &uvifs[nbr_delete->vifi]; - + /* Delete the entry from the pim_nbrs chain */ if (nbr_delete->prev != (pim_nbr_entry_t *)NULL) nbr_delete->prev->next = nbr_delete->next; @@ -272,7 +271,7 @@ delete_pim6_nbr(nbr_delete) v->uv_pim_neighbors = nbr_delete->next; if (nbr_delete->next != (pim_nbr_entry_t *)NULL) nbr_delete->next->prev = nbr_delete->prev; - + if (v->uv_pim_neighbors == (pim_nbr_entry_t *)NULL) { /* This was our last neighbor. */ v->uv_flags &= ~VIFF_PIM_NBR; @@ -286,7 +285,6 @@ delete_pim6_nbr(nbr_delete) * DR address, but the local address is the winner. */ v->uv_flags |= VIFF_DR; - v->uv_flags |= VIFF_QUERIER; } } @@ -299,16 +297,16 @@ delete_pim6_nbr(nbr_delete) for (srcentry_ptr = srclist; srcentry_ptr != (srcentry_t *)NULL; srcentry_ptr = srcentry_ptr_next) { srcentry_ptr_next = srcentry_ptr->next; - + /* The only time we don't need to scan all mrtentries is - * when the nbr was on the iif, but not the upstream nbr! + * when the nbr was on the iif, but not the upstream nbr! */ if (nbr_delete->vifi == srcentry_ptr->incoming && srcentry_ptr->upstream != nbr_delete) continue; /* Reset the next hop (PIM) router */ - if(srcentry_ptr->upstream == nbr_delete) + if(srcentry_ptr->upstream == nbr_delete) if (set_incoming(srcentry_ptr, PIM_IIF_SOURCE) == FALSE) { /* * Couldn't reset it. Sorry, the next hop router @@ -329,7 +327,7 @@ delete_pim6_nbr(nbr_delete) mrtentry_ptr->upstream = srcentry_ptr->upstream; mrtentry_ptr->metric = srcentry_ptr->metric; mrtentry_ptr->preference = srcentry_ptr->preference; - state_change = + state_change = change_interfaces(mrtentry_ptr, srcentry_ptr->incoming, &mrtentry_ptr->pruned_oifs, @@ -342,7 +340,7 @@ delete_pim6_nbr(nbr_delete) } } } - + free((char *)nbr_delete); } @@ -447,8 +445,8 @@ typedef struct { struct sockaddr_in6 group; u_int16 holdtime; } prune_delay_cbk_t; - -static void + +static void delayed_join_job(arg) void *arg; { @@ -458,7 +456,7 @@ delayed_join_job(arg) mrtentry_ptr = find_route(&cbk->source, &cbk->group, MRTF_SG, DONT_CREATE); - if(mrtentry_ptr == (mrtentry_t *)NULL) + if(mrtentry_ptr == (mrtentry_t *)NULL) return; if(mrtentry_ptr->join_delay_timerid) @@ -472,16 +470,16 @@ delayed_join_job(arg) free(cbk); } -static void -schedule_delayed_join(mrtentry_ptr, target) +static void +schedule_delayed_join(mrtentry_ptr, target) mrtentry_t *mrtentry_ptr; struct sockaddr_in6 *target; { u_long random_delay; join_delay_cbk_t *cbk; - + /* Delete existing timer */ - if(mrtentry_ptr->join_delay_timerid) + if(mrtentry_ptr->join_delay_timerid) timer_clearTimer(mrtentry_ptr->join_delay_timerid); #ifdef SYSV @@ -489,7 +487,7 @@ schedule_delayed_join(mrtentry_ptr, target) #else random_delay = random() % (long)PIM_RANDOM_DELAY_JOIN_TIMEOUT; #endif - + IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) log(LOG_DEBUG, 0, "Scheduling join for src %s, grp %s, delay %d", inet6_fmt(&mrtentry_ptr->source->address.sin6_addr), @@ -508,12 +506,12 @@ schedule_delayed_join(mrtentry_ptr, target) cbk->group = mrtentry_ptr->group->group; cbk->target = *target; - mrtentry_ptr->join_delay_timerid = + mrtentry_ptr->join_delay_timerid = timer_setTimer(random_delay, delayed_join_job, cbk); } -static void +static void delayed_prune_job(arg) void *arg; { @@ -525,9 +523,9 @@ delayed_prune_job(arg) mrtentry_ptr = find_route(&cbk->source, &cbk->group, MRTF_SG, DONT_CREATE); - if(mrtentry_ptr == (mrtentry_t *)NULL) + if(mrtentry_ptr == (mrtentry_t *)NULL) return; - + if(mrtentry_ptr->prune_delay_timerids[cbk->mifi]) timer_clearTimer(mrtentry_ptr->prune_delay_timerids[cbk->mifi]); @@ -535,7 +533,7 @@ delayed_prune_job(arg) IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) log(LOG_DEBUG, 0, "Deleting pruned mif %d for src %s, grp %s", - cbk->mifi, + cbk->mifi, inet6_fmt(&cbk->source.sin6_addr), inet6_fmt(&cbk->group.sin6_addr)); @@ -543,7 +541,7 @@ delayed_prune_job(arg) IF_SET(cbk->mifi, &new_pruned_oifs); SET_TIMER(mrtentry_ptr->prune_timers[cbk->mifi], cbk->holdtime); - state_change = + state_change = change_interfaces(mrtentry_ptr, mrtentry_ptr->incoming, &new_pruned_oifs, @@ -558,16 +556,16 @@ delayed_prune_job(arg) free(cbk); } -static void -schedule_delayed_prune(mrtentry_ptr, mifi, holdtime) +static void +schedule_delayed_prune(mrtentry_ptr, mifi, holdtime) mrtentry_t *mrtentry_ptr; mifi_t mifi; u_int16 holdtime; { prune_delay_cbk_t *cbk; - + /* Delete existing timer */ - if(mrtentry_ptr->prune_delay_timerids[mifi]) + if(mrtentry_ptr->prune_delay_timerids[mifi]) timer_clearTimer(mrtentry_ptr->prune_delay_timerids[mifi]); cbk = (prune_delay_cbk_t *)malloc(sizeof(prune_delay_cbk_t)); @@ -576,8 +574,8 @@ schedule_delayed_prune(mrtentry_ptr, mifi, holdtime) cbk->group = mrtentry_ptr->group->group; cbk->holdtime = holdtime; - mrtentry_ptr->prune_delay_timerids[mifi] = - timer_setTimer((u_int16)PIM_RANDOM_DELAY_JOIN_TIMEOUT, + mrtentry_ptr->prune_delay_timerids[mifi] = + timer_setTimer((u_int16)PIM_RANDOM_DELAY_JOIN_TIMEOUT, delayed_prune_job, cbk); } @@ -618,7 +616,7 @@ receive_pim6_join_prune(src, pim_message, datalen) inet6_fmt(&src->sin6_addr)); return(FALSE); } - + v = &uvifs[mifi]; if (uvifs[mifi].uv_flags & (VIFF_DOWN | VIFF_DISABLED | VIFF_NONBRS)) return(FALSE); /* Shoudn't come on this interface */ @@ -642,13 +640,13 @@ receive_pim6_join_prune(src, pim_message, datalen) inet6_fmt(&src->sin6_addr), inet6_fmt(&target.sin6_addr), holdtime); - + if (!inet6_localif_address(&target, v) && !IN6_IS_ADDR_UNSPECIFIED(&uni_target_addr.unicast_addr)) { /* if I am not the target of the join or prune message */ /* * Join Suppression: when receiving a join not addressed to me, - * if I am delaying a join for this (S,G) then cancel the delayed + * if I am delaying a join for this (S,G) then cancel the delayed * join. * Prune Soliticiting Joins: when receiving a prune not * addressed to me on a LAN, schedule delayed join if I have @@ -726,9 +724,9 @@ receive_pim6_join_prune(src, pim_message, datalen) s_flags = encod_src.flags; - /* if P2P link (not addressed to me) ignore + /* if P2P link (not addressed to me) ignore */ - if(uvifs[mifi].uv_flags & VIFF_POINT_TO_POINT) + if(uvifs[mifi].uv_flags & VIFF_POINT_TO_POINT) continue; /* @@ -736,7 +734,7 @@ receive_pim6_join_prune(src, pim_message, datalen) */ mrtentry_ptr = find_route(&source, &group, MRTF_SG, DONT_CREATE); - if(mrtentry_ptr == (mrtentry_t *)NULL) + if(mrtentry_ptr == (mrtentry_t *)NULL) continue; if(!(IF_ISEMPTY(&mrtentry_ptr->oifs))) { @@ -746,7 +744,7 @@ receive_pim6_join_prune(src, pim_message, datalen) "- scheduling delayed join", inet6_fmt(&source.sin6_addr), inet6_fmt(&group.sin6_addr)); - + schedule_delayed_join(mrtentry_ptr, &target); } @@ -759,7 +757,7 @@ receive_pim6_join_prune(src, pim_message, datalen) /* I am the target of this join/prune: * For joins, cancel delayed prunes that I have scheduled. - * For prunes, echo the prune and schedule delayed prunes on LAN or + * For prunes, echo the prune and schedule delayed prunes on LAN or * prune immediately on point-to-point links. */ else { @@ -797,10 +795,10 @@ receive_pim6_join_prune(src, pim_message, datalen) s_flags = encod_src.flags; MASKLEN_TO_MASK6(encod_src.masklen, s_mask); - + mrtentry_ptr = find_route(&source, &group, MRTF_SG, DONT_CREATE); - if(mrtentry_ptr == (mrtentry_t *)NULL) + if(mrtentry_ptr == (mrtentry_t *)NULL) continue; IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) @@ -814,7 +812,7 @@ receive_pim6_join_prune(src, pim_message, datalen) if(mrtentry_ptr->prune_delay_timerids[mifi]) { timer_clearTimer(mrtentry_ptr->prune_delay_timerids[mifi]); mrtentry_ptr->prune_delay_timerids[mifi] = 0; - } + } } while (num_p_srcs--) { @@ -829,7 +827,7 @@ receive_pim6_join_prune(src, pim_message, datalen) mrtentry_ptr = find_route(&source, &group, MRTF_SG, DONT_CREATE); - if(mrtentry_ptr == (mrtentry_t *)NULL) + if(mrtentry_ptr == (mrtentry_t *)NULL) continue; /* if P2P link (addressed to me) prune immediately @@ -844,10 +842,10 @@ receive_pim6_join_prune(src, pim_message, datalen) "mif", inet6_fmt(&source.sin6_addr), inet6_fmt(&group.sin6_addr)); - + IF_DEBUG(DEBUG_MRT) log(LOG_DEBUG, 0, "Deleting pruned mif %d for src %s, grp %s", - mifi, + mifi, inet6_fmt(&source.sin6_addr), inet6_fmt(&group.sin6_addr)); @@ -855,13 +853,13 @@ receive_pim6_join_prune(src, pim_message, datalen) IF_SET(mifi, &new_pruned_oifs); SET_TIMER(mrtentry_ptr->prune_timers[mifi], holdtime); - state_change = + state_change = change_interfaces(mrtentry_ptr, mrtentry_ptr->incoming, &new_pruned_oifs, &mrtentry_ptr->leaves, &mrtentry_ptr->asserted_oifs); - + /* Handle transition to negative cache */ if(state_change == -1) trigger_prune_alert(mrtentry_ptr); @@ -903,7 +901,7 @@ send_pim6_jp(mrtentry_ptr, action, mifi, target_addr, holdtime, echo) int echo; { u_int8 *data_ptr, *data_start_ptr; - + data_ptr = (u_int8 *)(pim6_send_buf + sizeof(struct pim)); data_start_ptr = data_ptr; @@ -911,7 +909,7 @@ send_pim6_jp(mrtentry_ptr, action, mifi, target_addr, holdtime, echo) /* No upstream neighbor - don't send */ return(FALSE); } - + IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) log(LOG_DEBUG, 0, "Sending %s: vif %s, src %s, group %s, " @@ -938,19 +936,19 @@ send_pim6_jp(mrtentry_ptr, action, mifi, target_addr, holdtime, echo) } else if(action == PIM_ACTION_PRUNE) { PUT_HOSTSHORT(0, data_ptr); PUT_HOSTSHORT(1, data_ptr); - } - + } + PUT_ESADDR6(mrtentry_ptr->source->address.sin6_addr, SINGLE_SRC_MSK6LEN, 0, data_ptr); /* Cancel active graft */ if (echo == 0) delete_pim6_graft_entry(mrtentry_ptr); - + send_pim6(pim6_send_buf, &uvifs[mifi].uv_linklocal->pa_addr, &allpim6routers_group, PIM_JOIN_PRUNE, data_ptr - data_start_ptr); - + return(TRUE); } @@ -988,7 +986,7 @@ receive_pim6_assert(src, pim_message, datalen) u_int8 local_wins; if_set new_pruned_oifs, new_leaves; int state_change; - + if ((mifi = find_vif_direct(src)) == NO_VIF) { /* Either a local vif or somehow received PIM_ASSERT from * non-directly connected router. Ignore it. @@ -999,7 +997,7 @@ receive_pim6_assert(src, pim_message, datalen) inet6_fmt(&src->sin6_addr)); return(FALSE); } - + v = &uvifs[mifi]; if (uvifs[mifi].uv_flags & (VIFF_DOWN | VIFF_DISABLED | VIFF_NONBRS)) return(FALSE); /* Shoudn't come on this interface */ @@ -1008,7 +1006,7 @@ receive_pim6_assert(src, pim_message, datalen) /* Get the group and source addresses */ GET_EGADDR6(&egaddr, data_ptr); GET_EUADDR6(&eusaddr, data_ptr); - + /* Get the metric related info */ GET_HOSTLONG(assert_preference, data_ptr); GET_HOSTLONG(assert_metric, data_ptr); @@ -1017,7 +1015,7 @@ receive_pim6_assert(src, pim_message, datalen) source.sin6_scope_id = inet6_uvif2scopeid(&source, v); group.sin6_addr = egaddr.mcast_addr; group.sin6_scope_id = inet6_uvif2scopeid(&group, v); - + IF_DEBUG(DEBUG_PIM_ASSERT) log(LOG_DEBUG, 0, "PIM Assert received from %s: src %s, grp %s, " @@ -1026,7 +1024,7 @@ receive_pim6_assert(src, pim_message, datalen) inet6_fmt(&source.sin6_addr), inet6_fmt(&group.sin6_addr), assert_preference, assert_metric); - + if ((mrtentry_ptr = find_route(&source, &group, MRTF_SG, CREATE)) == NULL) { IF_DEBUG(DEBUG_PIM_ASSERT) @@ -1040,17 +1038,17 @@ receive_pim6_assert(src, pim_message, datalen) /* For some reason, it's possible for asserts to be processed * before the data alerts a cache miss. Therefore, when an * assert is received, create (S,G) state and continue, since - * we know by the assert that there are upstream forwarders. + * we know by the assert that there are upstream forwarders. */ IF_DEBUG(DEBUG_PIM_ASSERT) log(LOG_DEBUG, 0, "\tNo MRT entry - creating..."); mrtentry_ptr->flags &= ~MRTF_NEW; - /* Set oifs */ + /* Set oifs */ set_leaves(mrtentry_ptr); calc_oifs(mrtentry_ptr, &(mrtentry_ptr->oifs)); - + /* Add it to the kernel */ k_chg_mfc(mld6_socket, &source, &group, mrtentry_ptr->incoming, &mrtentry_ptr->oifs); @@ -1061,7 +1059,7 @@ receive_pim6_assert(src, pim_message, datalen) /* No need to call change_interfaces, but check for NULL oiflist */ if(IF_ISEMPTY(&mrtentry_ptr->oifs)) - trigger_prune_alert(mrtentry_ptr); + trigger_prune_alert(mrtentry_ptr); } /* If arrived on iif, I'm downstream of the asserted LAN. @@ -1073,13 +1071,13 @@ receive_pim6_assert(src, pim_message, datalen) /* Determine local (really that of upstream nbr!) pref/metric */ local_metric = mrtentry_ptr->metric; local_preference = mrtentry_ptr->preference; - + if(mrtentry_ptr->upstream && inet6_equal(&mrtentry_ptr->upstream->address, src) && assert_preference == local_preference && assert_metric == local_metric) - /* if assert from previous winner w/ same pref/metric, + /* if assert from previous winner w/ same pref/metric, * then assert sender wins again */ local_wins = FALSE; @@ -1092,7 +1090,7 @@ receive_pim6_assert(src, pim_message, datalen) assert_metric, src); /* - * This is between the assert sender and previous winner or rpf + * This is between the assert sender and previous winner or rpf * (who is the "local" in this case). */ if(local_wins == TRUE) { @@ -1121,7 +1119,7 @@ receive_pim6_assert(src, pim_message, datalen) mrtentry_ptr->flags |= MRTF_ASSERTED; /* Send a join for the S,G if oiflist is non-empty */ - if(!(IF_ISEMPTY(&mrtentry_ptr->oifs))) + if(!(IF_ISEMPTY(&mrtentry_ptr->oifs))) send_pim6_jp(mrtentry_ptr, PIM_ACTION_JOIN, mrtentry_ptr->incoming, src, 0, 0); @@ -1129,7 +1127,7 @@ receive_pim6_assert(src, pim_message, datalen) /* If the assert arrived on an oif: */ else { - if(!(IF_ISSET(mifi, &mrtentry_ptr->oifs))) + if(!(IF_ISSET(mifi, &mrtentry_ptr->oifs))) return(FALSE); /* assert arrived on oif ==> I'm a upstream router */ @@ -1154,7 +1152,7 @@ receive_pim6_assert(src, pim_message, datalen) IF_COPY(&mrtentry_ptr->pruned_oifs, &new_pruned_oifs); IF_SET(mifi, &new_pruned_oifs); IF_SET(mifi, &mrtentry_ptr->asserted_oifs); - SET_TIMER(mrtentry_ptr->prune_timers[mifi], + SET_TIMER(mrtentry_ptr->prune_timers[mifi], PIM_JOIN_PRUNE_HOLDTIME); if (IF_ISSET(mifi, &mrtentry_ptr->leaves)) { @@ -1191,7 +1189,7 @@ receive_pim6_assert(src, pim_message, datalen) IF_DEBUG(DEBUG_PIM_ASSERT) log(LOG_DEBUG, 0, "\tAssert sender %s loses - " - "sending assert and scheuling prune", + "sending assert and scheuling prune", inet6_fmt(&src->sin6_addr)); if(!(IF_ISSET(mifi, &mrtentry_ptr->leaves))) { @@ -1201,19 +1199,19 @@ receive_pim6_assert(src, pim_message, datalen) send_pim6_jp(mrtentry_ptr, PIM_ACTION_PRUNE, mifi, &v->uv_linklocal->pa_addr, PIM_JOIN_PRUNE_HOLDTIME, 0); - schedule_delayed_prune(mrtentry_ptr, mifi, + schedule_delayed_prune(mrtentry_ptr, mifi, PIM_JOIN_PRUNE_HOLDTIME); } send_pim6_assert(&source, &group, mifi, mrtentry_ptr); } } /* if assert on oif */ - + return(TRUE); } -int +int send_pim6_assert(source, group, mifi, mrtentry_ptr) struct sockaddr_in6 *source; struct sockaddr_in6 *group; @@ -1305,10 +1303,10 @@ delete_pim6_graft_entry(mrtentry_ptr) if(mrtentry_ptr->graft == (pim_graft_entry_t *)NULL) return; graft_entry = mrtentry_ptr->graft; - + if(graft_entry->prev) graft_entry->prev->next = graft_entry->next; - else + else graft_list = graft_entry->next; if(graft_entry->next) graft_entry->next->prev = graft_entry->prev; @@ -1328,7 +1326,7 @@ retransmit_pim6_graft(mrtentry_ptr) mrtentry_t *mrtentry_ptr; { u_int8 *data_ptr, *data_start_ptr; - + data_ptr = (u_int8 *)(pim6_send_buf + sizeof(struct pim)); data_start_ptr = data_ptr; @@ -1380,10 +1378,10 @@ retransmit_all_pim6_grafts(arg) IF_DEBUG(DEBUG_PIM_GRAFT) log(LOG_DEBUG, 0, "Retransmitting all pending PIM-Grafts"); + - - for(graft_ptr = graft_list; - graft_ptr != NULL; + for(graft_ptr = graft_list; + graft_ptr != NULL; graft_ptr = graft_ptr->next) { IF_DEBUG(DEBUG_PIM_GRAFT) @@ -1453,7 +1451,7 @@ receive_pim6_graft(src, pim_message, datalen, pimtype) "PIM %s received from %s on mif %d, grps: %d", pimtype == PIM_GRAFT ? "GRAFT" : "GRAFT-ACK", inet6_fmt(&src->sin6_addr), mifi, num_groups); - + group.sin6_len = sizeof(group); group.sin6_family = AF_INET6; source.sin6_len = sizeof(source); @@ -1477,7 +1475,7 @@ receive_pim6_graft(src, pim_message, datalen, pimtype) (num_j_srcs + num_p_srcs) * sizeof(pim6_encod_src_addr_t); continue; /* Ignore this group and jump to the next */ } - + while (num_j_srcs--) { GET_ESADDR6(&encod_src, data_ptr); if (encod_src.masklen > (sizeof(struct in6_addr) << 3)) @@ -1491,7 +1489,7 @@ receive_pim6_graft(src, pim_message, datalen, pimtype) mrtentry_ptr = find_route(&source, &group, MRTF_SG, DONT_CREATE); - if(mrtentry_ptr == (mrtentry_t *)NULL) + if(mrtentry_ptr == (mrtentry_t *)NULL) continue; if(pimtype == PIM_GRAFT) { @@ -1508,14 +1506,14 @@ receive_pim6_graft(src, pim_message, datalen, pimtype) if(mrtentry_ptr->prune_delay_timerids[mifi]) { timer_clearTimer(mrtentry_ptr->prune_delay_timerids[mifi]); mrtentry_ptr->prune_delay_timerids[mifi] = 0; - } - + } + /* Add to oiflist (unprune) */ if (IF_ISSET(mifi, &mrtentry_ptr->pruned_oifs)) { IF_CLR(mifi, &mrtentry_ptr->pruned_oifs); IF_CLR(mifi, &mrtentry_ptr->asserted_oifs); SET_TIMER(mrtentry_ptr->prune_timers[mifi], 0); - state_change = + state_change = change_interfaces(mrtentry_ptr, mrtentry_ptr->incoming, &mrtentry_ptr->pruned_oifs, @@ -1555,7 +1553,7 @@ receive_pim6_graft(src, pim_message, datalen, pimtype) return(TRUE); } -int +int send_pim6_graft(mrtentry_ptr) mrtentry_t *mrtentry_ptr; { @@ -1574,7 +1572,7 @@ send_pim6_graft(mrtentry_ptr) /* Set up retransmission */ new_graft = (pim_graft_entry_t *)malloc(sizeof(pim_graft_entry_t)); if (new_graft == (pim_graft_entry_t *)NULL) { - log(LOG_WARNING, 0, + log(LOG_WARNING, 0, "Memory allocation error for graft entry src %s, grp %s", inet6_fmt(&mrtentry_ptr->source->address.sin6_addr), inet6_fmt(&mrtentry_ptr->group->group.sin6_addr)); @@ -1589,9 +1587,9 @@ send_pim6_graft(mrtentry_ptr) mrtentry_ptr->graft = new_graft; /* Set up timer if not running */ - if(!graft_retrans_timer) + if(!graft_retrans_timer) graft_retrans_timer = timer_setTimer(PIM_GRAFT_RETRANS_PERIOD, - retransmit_all_pim6_grafts, + retransmit_all_pim6_grafts, (void *)NULL); return(TRUE); diff --git a/usr.sbin/pim6dd/pim6dd.8 b/usr.sbin/pim6dd/pim6dd.8 index 959a497ce3633..409f5f93fdf1f 100644 --- a/usr.sbin/pim6dd/pim6dd.8 +++ b/usr.sbin/pim6dd/pim6dd.8 @@ -1,6 +1,6 @@ .\" 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: @@ -12,7 +12,7 @@ .\" 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 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: pim6dd.8,v 1.3 1999/08/13 09:20:43 jinmei Exp $ +.\" $Id: pim6dd.8,v 1.5 2000/05/18 16:11:46 itojun Exp $ .\" $FreeBSD$ .\" .Dd Nov 17, 1998 @@ -55,8 +55,7 @@ By default, .Pa /etc/pim6dd.conf is used. .It Fl d -Specify debug levels. -If this option is specified without any arguments, +Specify debug levels. If this option is specified without any arguments, all debug messages will be printed out. A subset of the messages to be printed out can be specified as arguments of the option. @@ -68,7 +67,7 @@ and .Ic asserts. .El .Pp -.Nm Pim6dd +.Nm Pim6dd automatically configures itself to forward on all multicast-capable interfaces, i.e., interfaces that have the IFF_MULTICAST flag set (excluding the "loopback interface"). @@ -93,7 +92,7 @@ The default configuration file. The .Nm command is based on -.Nm pimdd, +.Nm pimdd , which is an IPv4 multicast routing daemon developed at the University of Oregon. .Nm Pimdd @@ -101,19 +100,15 @@ has been derived from PIM sparse-mode .Nm pimd developed at University of Southern California. Part of these two programs above has also been derived from -.Nm mrouted. +.Nm mrouted . .Nm Mrouted is COPYRIGHT 1989 by The Board of Trustees of Leland Stanford Junior University. -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 .\" .Sh BUGS .Nm Pim6dd does not contain any unicast routing engine, so a unicast routing -daemon needs to run on the system. +daemon needs to run on the system. .Pp The kernel unicast routing table is periodically polled by .Nm diff --git a/usr.sbin/pim6dd/pim6dd.conf.5 b/usr.sbin/pim6dd/pim6dd.conf.5 index 82d7531e5e4e0..763635470ca18 100644 --- a/usr.sbin/pim6dd/pim6dd.conf.5 +++ b/usr.sbin/pim6dd/pim6dd.conf.5 @@ -1,6 +1,6 @@ .\" 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: @@ -12,7 +12,7 @@ .\" 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 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: pim6dd.conf.5,v 1.2 1999/12/10 06:08:49 itojun Exp $ +.\" KAME Id: pim6dd.conf.5,v 1.4 2000/07/09 17:26:52 itojun Exp .\" $FreeBSD$ .\" .Dd Nov 17, 1998 @@ -33,10 +33,11 @@ .Os .Sh NAME .Nm pim6dd.conf -.Nd "config file for pim6dd, PIM for IPv6 dense mode daemon" +.Nd config file for pim6dd, PIM for IPv6 dense mode daemon +.\" .Sh DESCRIPTION The file describes how the -.Nm pim6dd +.Xr pim6dd 8 daemon treats each interface on the system. By default(including the case where there is no configuration file), PIM will be activated on all interfaces, which can be overridden @@ -53,15 +54,14 @@ There are four types of configuration commands: Specifies a default preference value when sending a PIM assert message. Preferences are used by assert elections to determine upstream routers. Currently -.Nm +.Xr pim6dd 8 cannot reliably obtain preferences and metrics from the unicast routing protocols, so a default value may be configured. .\" .It Ic default_source_metric Ar metric Specifies a default metric value when sending a PIM assert message. It is recommended that preferences be set such that metrics are never -consulted. -However, default metrics may also be set and will default to +consulted. However, default metrics may also be set and will default to 1024. .\" .It Xo @@ -69,7 +69,7 @@ However, default metrics may also be set and will default to .Op disable .Xc Specifies -.Nm +.Xr pim6dd 8 to ignore the interface even if the interface is multicast-capable. Interfaces are specified in the form of "name unit", such as .Ar gif0 @@ -87,15 +87,14 @@ assert message on the interface. .It Xo .Ic filter Ar groupaddrs Ar interfaces... .Xc -Specifies an output filter. -If an incoming multicast packet's destination +Specifies an output filter. If an incoming multicast packet's destination matches the specified .Ar groupaddrs , the packet is not sent on the .Ar interfaces. Moreover, if there is no other interface than the specified interfaces, -.Nm pim6dd +.Xr pim6dd 8 sends a prune message to the upstream neighbor. Valid formats of .Ar groupaddrs @@ -122,8 +121,7 @@ is omitted, it means the exact match for .Ar multicastaddr. .El .Ar interfaces -are specified as a blank separated list of interfaces. -Each interface is +are specified as a blank separated list of interfaces. Each interface is specified in the form of "name unit". .El .\" @@ -139,20 +137,20 @@ filter ff18::1000-ff18::1050 gif3 .Xr pim6dd 8 .Sh HISTORY The -.Nm pim6dd +.Xr pim6dd 8 command and the configuration file .Nm are based on .Nm pimdd , which is an IPv4 multicast routing daemon developed at the University of Oregon. -.Nm Pimdd +.Nm pimdd has been derived from PIM sparse-mode .Nm pimd developed at University of Southern California. Part of these two programs above has also been derived from -.Nm mrouted. -.Nm Mrouted +.Nm mrouted . +.Nm mrouted is COPYRIGHT 1989 by The Board of Trustees of Leland Stanford Junior University. .Pp diff --git a/usr.sbin/pim6dd/pimdd.h b/usr.sbin/pim6dd/pimdd.h index 31b46d58d6c76..73880f6e05fa0 100644 --- a/usr.sbin/pim6dd/pimdd.h +++ b/usr.sbin/pim6dd/pimdd.h @@ -10,15 +10,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -30,7 +30,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * * $Id: pimdd.h,v 1.1.1.1 1999/08/08 23:30:53 itojun Exp $ @@ -39,13 +39,13 @@ * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * @@ -54,45 +54,45 @@ #include <netinet6/pim6.h> -#define PIM_PROTOCOL_VERSION 2 -#define PIMD_VERSION PIM_PROTOCOL_VERSION -#define PIMD_SUBVERSION 1 +#define PIM_PROTOCOL_VERSION 2 +#define PIMD_VERSION PIM_PROTOCOL_VERSION +#define PIMD_SUBVERSION 1 #if 0 -#define PIM_CONSTANT 0x000eff00 /* constant portion of 'group' field */ +#define PIM_CONSTANT 0x000eff00 /* constant portion of 'group' field */ #endif -#define PIM_CONSTANT 0 -#define PIMD_LEVEL (PIM_CONSTANT | PIMD_VERSION | (PIMD_SUBVERSION << 8)) +#define PIM_CONSTANT 0 +#define PIMD_LEVEL (PIM_CONSTANT | PIMD_VERSION | (PIMD_SUBVERSION << 8)) -#define INADDR_ALL_PIM_ROUTERS (u_int32)0xe000000D /* 224.0.0.13 */ +#define INADDR_ALL_PIM_ROUTERS (u_int32)0xe000000D /* 224.0.0.13 */ /* PIM protocol timers (in seconds) */ #ifndef TIMER_INTERVAL -#define TIMER_INTERVAL 5 /* virtual timer granularity */ +#define TIMER_INTERVAL 5 /* virtual timer granularity */ #endif /* TIMER_INTERVAL */ -#define PIM_DATA_TIMEOUT 210 -#define PIM_TIMER_HELLO_PERIOD 30 -#define PIM_JOIN_PRUNE_HOLDTIME 210 -#define PIM_RANDOM_DELAY_JOIN_TIMEOUT 3 -#define PIM_GRAFT_RETRANS_PERIOD 3 -#define PIM_TIMER_HELLO_HOLDTIME (3.5 * PIM_TIMER_HELLO_PERIOD) -#define PIM_ASSERT_TIMEOUT 210 +#define PIM_DATA_TIMEOUT 210 +#define PIM_TIMER_HELLO_PERIOD 30 +#define PIM_JOIN_PRUNE_HOLDTIME 210 +#define PIM_RANDOM_DELAY_JOIN_TIMEOUT 3 +#define PIM_GRAFT_RETRANS_PERIOD 3 +#define PIM_TIMER_HELLO_HOLDTIME (3.5 * PIM_TIMER_HELLO_PERIOD) +#define PIM_ASSERT_TIMEOUT 210 /* Misc definitions */ -#define SINGLE_SRC_MSKLEN 32 /* the single source mask length */ -#define SINGLE_GRP_MSKLEN 32 /* the single group mask length */ +#define SINGLE_SRC_MSKLEN 32 /* the single source mask length */ +#define SINGLE_GRP_MSKLEN 32 /* the single group mask length */ -#define SINGLE_SRC_MSK6LEN 128 /* the single source mask length for IPv6*/ -#define SINGLE_GRP_MSK6LEN 128 /* the single group mask length for IPv6*/ +#define SINGLE_SRC_MSK6LEN 128 /* the single source mask length for IPv6*/ +#define SINGLE_GRP_MSK6LEN 128 /* the single group mask length for IPv6*/ /* TODO: change? */ -#define PIM_GROUP_PREFIX_DEFAULT_MASKLEN 16 /* The default group masklen if +#define PIM_GROUP_PREFIX_DEFAULT_MASKLEN 16 /* The default group masklen if * omitted in the config file. */ -#define UCAST_ROUTING_CHECK_INTERVAL 20 /* Unfortunately, if the unicast +#define UCAST_ROUTING_CHECK_INTERVAL 20 /* Unfortunately, if the unicast * routing changes, the kernel * or any of the existing * unicast routing daemons @@ -104,40 +104,40 @@ */ -#define DEFAULT_PHY_RATE_LIMIT 0 /* default phyint rate limit */ +#define DEFAULT_PHY_RATE_LIMIT 0 /* default phyint rate limit */ -#define DEFAULT_LOCAL_PREF 101 /* Default assert preference */ -#define DEFAULT_LOCAL_METRIC 1024 /* Default assert metric */ +#define DEFAULT_LOCAL_PREF 101 /* Default assert preference */ +#define DEFAULT_LOCAL_METRIC 1024 /* Default assert metric */ /************************************************************************** * PIM Encoded-Unicast, Encoded-Group and Encoded-Source Address formats * *************************************************************************/ /* Address families definition */ -#define ADDRF_RESERVED 0 -#define ADDRF_IPv4 1 -#define ADDRF_IPv6 2 -#define ADDRF_NSAP 3 -#define ADDRF_HDLC 4 -#define ADDRF_BBN1822 5 -#define ADDRF_802 6 -#define ADDRF_ETHERNET ADDRF_802 -#define ADDRF_E163 7 -#define ADDRF_E164 8 -#define ADDRF_SMDS ADDRF_E164 -#define ADDRF_ATM ADDRF_E164 -#define ADDRF_F69 9 -#define ADDRF_TELEX ADDRF_F69 -#define ADDRF_X121 10 -#define ADDRF_X25 ADDRF_X121 -#define ADDRF_IPX 11 -#define ADDRF_APPLETALK 12 -#define ADDRF_DECNET_IV 13 -#define ADDRF_BANYAN 14 -#define ADDRF_E164_NSAP 15 +#define ADDRF_RESERVED 0 +#define ADDRF_IPv4 1 +#define ADDRF_IPv6 2 +#define ADDRF_NSAP 3 +#define ADDRF_HDLC 4 +#define ADDRF_BBN1822 5 +#define ADDRF_802 6 +#define ADDRF_ETHERNET ADDRF_802 +#define ADDRF_E163 7 +#define ADDRF_E164 8 +#define ADDRF_SMDS ADDRF_E164 +#define ADDRF_ATM ADDRF_E164 +#define ADDRF_F69 9 +#define ADDRF_TELEX ADDRF_F69 +#define ADDRF_X121 10 +#define ADDRF_X25 ADDRF_X121 +#define ADDRF_IPX 11 +#define ADDRF_APPLETALK 12 +#define ADDRF_DECNET_IV 13 +#define ADDRF_BANYAN 14 +#define ADDRF_E164_NSAP 15 /* Addresses Encoding Type (specific for each Address Family */ -#define ADDRT_IPv4 0 -#define ADDRT_IPv6 0 +#define ADDRT_IPv4 0 +#define ADDRT_IPv6 0 #if 0 /* XXX: the definition is for IPv4 only */ @@ -200,9 +200,9 @@ typedef struct pim6_encod_src_addr_ { u_int8 masklen; struct in6_addr src_addr; } pim6_encod_src_addr_t; -#define USADDR_RP_BIT 0x1 -#define USADDR_WC_BIT 0x2 -#define USADDR_S_BIT 0x4 +#define USADDR_RP_BIT 0x1 +#define USADDR_WC_BIT 0x2 +#define USADDR_S_BIT 0x4 /************************************************************************** * PIM Messages formats * @@ -233,56 +233,56 @@ typedef struct pim_jp_encod_grp_ { } pim_jp_encod_grp_t; #endif -#define PIM_ACTION_NOTHING 0 -#define PIM_ACTION_JOIN 1 -#define PIM_ACTION_PRUNE 2 +#define PIM_ACTION_NOTHING 0 +#define PIM_ACTION_JOIN 1 +#define PIM_ACTION_PRUNE 2 -#define PIM_IIF_SOURCE 1 -#define PIM_IIF_RP 2 +#define PIM_IIF_SOURCE 1 +#define PIM_IIF_RP 2 -#define PIM_ASSERT_RPT_BIT 0x80000000 +#define PIM_ASSERT_RPT_BIT 0x80000000 /* PIM messages type */ -#define PIM_HELLO 0 +#define PIM_HELLO 0 #ifndef PIM_REGISTER -#define PIM_REGISTER 1 +#define PIM_REGISTER 1 #endif -#define PIM_REGISTER_STOP 2 -#define PIM_JOIN_PRUNE 3 -#define PIM_BOOTSTRAP 4 -#define PIM_ASSERT 5 -#define PIM_GRAFT 6 -#define PIM_GRAFT_ACK 7 -#define PIM_CAND_RP_ADV 8 +#define PIM_REGISTER_STOP 2 +#define PIM_JOIN_PRUNE 3 +#define PIM_BOOTSTRAP 4 +#define PIM_ASSERT 5 +#define PIM_GRAFT 6 +#define PIM_GRAFT_ACK 7 +#define PIM_CAND_RP_ADV 8 -#define PIM_V2_HELLO PIM_HELLO -#define PIM_V2_REGISTER PIM_REGISTER -#define PIM_V2_REGISTER_STOP PIM_REGISTER_STOP -#define PIM_V2_JOIN_PRUNE PIM_JOIN_PRUNE -#define PIM_V2_BOOTSTRAP PIM_BOOTSTRAP -#define PIM_V2_ASSERT PIM_ASSERT -#define PIM_V2_GRAFT PIM_GRAFT -#define PIM_V2_GRAFT_ACK PIM_GRAFT_ACK -#define PIM_V2_CAND_RP_ADV PIM_CAND_RP_ADV +#define PIM_V2_HELLO PIM_HELLO +#define PIM_V2_REGISTER PIM_REGISTER +#define PIM_V2_REGISTER_STOP PIM_REGISTER_STOP +#define PIM_V2_JOIN_PRUNE PIM_JOIN_PRUNE +#define PIM_V2_BOOTSTRAP PIM_BOOTSTRAP +#define PIM_V2_ASSERT PIM_ASSERT +#define PIM_V2_GRAFT PIM_GRAFT +#define PIM_V2_GRAFT_ACK PIM_GRAFT_ACK +#define PIM_V2_CAND_RP_ADV PIM_CAND_RP_ADV -#define PIM_V1_QUERY 0 -#define PIM_V1_REGISTER 1 -#define PIM_V1_REGISTER_STOP 2 -#define PIM_V1_JOIN_PRUNE 3 -#define PIM_V1_RP_REACHABILITY 4 -#define PIM_V1_ASSERT 5 -#define PIM_V1_GRAFT 6 -#define PIM_V1_GRAFT_ACK 7 +#define PIM_V1_QUERY 0 +#define PIM_V1_REGISTER 1 +#define PIM_V1_REGISTER_STOP 2 +#define PIM_V1_JOIN_PRUNE 3 +#define PIM_V1_RP_REACHABILITY 4 +#define PIM_V1_ASSERT 5 +#define PIM_V1_GRAFT 6 +#define PIM_V1_GRAFT_ACK 7 /* Vartious options from PIM messages definitions */ /* PIM_HELLO definitions */ -#define PIM_MESSAGE_HELLO_HOLDTIME 1 -#define PIM_MESSAGE_HELLO_HOLDTIME_LENGTH 2 -#define PIM_MESSAGE_HELLO_HOLDTIME_FOREVER 0xffff +#define PIM_MESSAGE_HELLO_HOLDTIME 1 +#define PIM_MESSAGE_HELLO_HOLDTIME_LENGTH 2 +#define PIM_MESSAGE_HELLO_HOLDTIME_FOREVER 0xffff -#define MASK_TO_MASKLEN(mask, masklen) \ +#define MASK_TO_MASKLEN(mask, masklen) \ do { \ register u_int32 tmp_mask = ntohl((mask)); \ register u_int8 tmp_masklen = sizeof((mask)) << 3; \ @@ -292,12 +292,12 @@ typedef struct pim_jp_encod_grp_ { (masklen) = tmp_masklen; \ } while (0) -#define MASKLEN_TO_MASK(masklen, mask) \ +#define MASKLEN_TO_MASK(masklen, mask) \ do { \ (mask) = (masklen)? htonl(~0 << ((sizeof((mask)) << 3) - (masklen))) : 0;\ } while (0) -#define MASKLEN_TO_MASK6(masklen, mask6) \ +#define MASKLEN_TO_MASK6(masklen, mask6) \ do {\ u_char maskarray[8] = \ {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; \ @@ -326,10 +326,10 @@ do { \ * GET_HOSTLONG gets the data, but in the memory it is in "host order" * The same for all {PUT,GET}_{NET,HOST}{SHORT,LONG} */ -#define GET_BYTE(val, cp) ((val) = *(cp)++) -#define PUT_BYTE(val, cp) (*(cp)++ = (u_int8)(val)) +#define GET_BYTE(val, cp) ((val) = *(cp)++) +#define PUT_BYTE(val, cp) (*(cp)++ = (u_int8)(val)) -#define GET_HOSTSHORT(val, cp) \ +#define GET_HOSTSHORT(val, cp) \ do { \ register u_int16 Xv; \ Xv = (*(cp)++) << 8; \ @@ -337,7 +337,7 @@ do { \ (val) = Xv; \ } while (0) -#define PUT_HOSTSHORT(val, cp) \ +#define PUT_HOSTSHORT(val, cp) \ do { \ register u_int16 Xv; \ Xv = (u_int16)(val); \ @@ -346,14 +346,14 @@ do { \ } while (0) #if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN) -#define GET_NETSHORT(val, cp) \ +#define GET_NETSHORT(val, cp) \ do { \ register u_int16 Xv; \ Xv = *(cp)++; \ Xv |= (*(cp)++) << 8; \ (val) = Xv; \ } while (0) -#define PUT_NETSHORT(val, cp) \ +#define PUT_NETSHORT(val, cp) \ do { \ register u_int16 Xv; \ Xv = (u_int16)(val); \ @@ -361,11 +361,11 @@ do { \ *(cp)++ = (u_int8)(Xv >> 8); \ } while (0) #else -#define GET_NETSHORT(val, cp) GET_HOSTSHORT(val, cp) -#define PUT_NETSHORT(val, cp) PUT_HOSTSHORT(val, cp) +#define GET_NETSHORT(val, cp) GET_HOSTSHORT(val, cp) +#define PUT_NETSHORT(val, cp) PUT_HOSTSHORT(val, cp) #endif /* {GET,PUT}_NETSHORT */ -#define GET_HOSTLONG(val, cp) \ +#define GET_HOSTLONG(val, cp) \ do { \ register u_long Xv; \ Xv = (*(cp)++) << 24; \ @@ -375,7 +375,7 @@ do { \ (val) = Xv; \ } while (0) -#define PUT_HOSTLONG(val, cp) \ +#define PUT_HOSTLONG(val, cp) \ do { \ register u_int32 Xv; \ Xv = (u_int32)(val); \ @@ -386,7 +386,7 @@ do { \ } while (0) #if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN) -#define GET_NETLONG(val, cp) \ +#define GET_NETLONG(val, cp) \ do { \ register u_long Xv; \ Xv = *(cp)++; \ @@ -396,7 +396,7 @@ do { \ (val) = Xv; \ } while (0) -#define PUT_NETLONG(val, cp) \ +#define PUT_NETLONG(val, cp) \ do { \ register u_int32 Xv; \ Xv = (u_int32)(val); \ @@ -406,12 +406,12 @@ do { \ *(cp)++ = (u_int8)(Xv >> 24); \ } while (0) #else -#define GET_NETLONG(val, cp) GET_HOSTLONG(val, cp) -#define PUT_NETLONG(val, cp) PUT_HOSTLONG(val, cp) +#define GET_NETLONG(val, cp) GET_HOSTLONG(val, cp) +#define PUT_NETLONG(val, cp) PUT_HOSTLONG(val, cp) #endif /* {GET,PUT}_HOSTLONG */ -#define GET_ESADDR(esa, cp) \ +#define GET_ESADDR(esa, cp) \ do { \ (esa)->addr_family = *(cp)++; \ (esa)->encod_type = *(cp)++; \ @@ -420,7 +420,7 @@ do { \ GET_NETLONG((esa)->src_addr, (cp)); \ } while(0) -#define GET_ESADDR6(esa, cp) /* XXX: hard coding */ \ +#define GET_ESADDR6(esa, cp) /* XXX: hard coding */ \ do { \ (esa)->addr_family = *(cp)++; \ (esa)->encod_type = *(cp)++; \ @@ -430,7 +430,7 @@ do { \ (cp) += sizeof(struct in6_addr); \ } while(0) -#define PUT_ESADDR(addr, masklen, flags, cp) \ +#define PUT_ESADDR(addr, masklen, flags, cp) \ do { \ u_int32 mask; \ MASKLEN_TO_MASK((masklen), mask); \ @@ -441,7 +441,7 @@ do { \ PUT_NETLONG((addr) & mask, (cp)); \ } while(0) -#define PUT_ESADDR6(addr, masklen, flags, cp) \ +#define PUT_ESADDR6(addr, masklen, flags, cp) \ do { \ int i; \ struct in6_addr maskaddr; \ @@ -454,7 +454,7 @@ do { \ *(cp) = maskaddr.s6_addr[i] & (addr).s6_addr[i]; \ } while(0) -#define GET_EGADDR(ega, cp) \ +#define GET_EGADDR(ega, cp) \ do { \ (ega)->addr_family = *(cp)++; \ (ega)->encod_type = *(cp)++; \ @@ -463,7 +463,7 @@ do { \ GET_NETLONG((ega)->mcast_addr, (cp)); \ } while(0) -#define GET_EGADDR6(ega, cp) /* XXX: hard coding */ \ +#define GET_EGADDR6(ega, cp) /* XXX: hard coding */ \ do { \ (ega)->addr_family = *(cp)++; \ (ega)->encod_type = *(cp)++; \ @@ -473,7 +473,7 @@ do { \ (cp) += sizeof(struct in6_addr); \ } while(0) -#define PUT_EGADDR(addr, masklen, reserved, cp) \ +#define PUT_EGADDR(addr, masklen, reserved, cp) \ do { \ u_int32 mask; \ MASKLEN_TO_MASK((masklen), mask); \ @@ -484,7 +484,7 @@ do { \ PUT_NETLONG((addr) & mask, (cp)); \ } while(0) -#define PUT_EGADDR6(addr, masklen, reserved, cp) \ +#define PUT_EGADDR6(addr, masklen, reserved, cp) \ do { \ int i; \ struct in6_addr maskaddr; \ @@ -497,14 +497,14 @@ do { \ *(cp) = maskaddr.s6_addr[i] & (addr).s6_addr[i]; \ } while(0) -#define GET_EUADDR(eua, cp) \ +#define GET_EUADDR(eua, cp) \ do { \ (eua)->addr_family = *(cp)++; \ (eua)->encod_type = *(cp)++; \ GET_NETLONG((eua)->unicast_addr, (cp)); \ } while(0) -#define GET_EUADDR6(eua, cp) /* XXX hard conding */ \ +#define GET_EUADDR6(eua, cp) /* XXX hard conding */ \ do { \ (eua)->addr_family = *(cp)++; \ (eua)->encod_type = *(cp)++; \ @@ -512,14 +512,14 @@ do { \ (cp) += sizeof(struct in6_addr); \ } while(0) -#define PUT_EUADDR(addr, cp) \ +#define PUT_EUADDR(addr, cp) \ do { \ *(cp)++ = ADDRF_IPv4; /* family */ \ *(cp)++ = ADDRT_IPv4; /* type */ \ PUT_NETLONG((addr), (cp)); \ } while(0) -#define PUT_EUADDR6(addr, cp) \ +#define PUT_EUADDR6(addr, cp) \ do { \ *(cp)++ = ADDRF_IPv6; /* family */ \ *(cp)++ = ADDRT_IPv6; /* type */ \ @@ -530,21 +530,21 @@ do { \ /* TODO: Currently not used. Probably not need at all. Delete! */ #ifdef NOSUCHDEF /* This is completely IGMP related stuff? */ -#define PIM_LEAF_TIMEOUT (3.5 * IGMP_QUERY_INTERVAL) +#define PIM_LEAF_TIMEOUT (3.5 * IGMP_QUERY_INTERVAL) #endif /* NOSUCHDEF */ #if defined(__bsdi__) || defined(__NetBSD__) /* * Struct used to communicate from kernel to multicast router * note the convenient similarity to an IP packet - */ + */ struct igmpmsg { u_long unused1; u_long unused2; u_char im_msgtype; /* what type of message */ -#define IGMPMSG_NOCACHE 1 -#define IGMPMSG_WRONGVIF 2 -#define IGMPMSG_WHOLEPKT 3 /* used for user level encap*/ +#define IGMPMSG_NOCACHE 1 +#define IGMPMSG_WRONGVIF 2 +#define IGMPMSG_WHOLEPKT 3 /* used for user level encap*/ u_char im_mbz; /* must be zero */ u_char im_vif; /* vif rec'd on */ u_char unused3; diff --git a/usr.sbin/pim6dd/route.c b/usr.sbin/pim6dd/route.c index 6684f2ca827f9..8a39ae08dcb23 100644 --- a/usr.sbin/pim6dd/route.c +++ b/usr.sbin/pim6dd/route.c @@ -10,15 +10,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -30,7 +30,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * * $Id: route.c,v 1.3 1999/10/27 11:40:30 jinmei Exp $ @@ -39,13 +39,13 @@ * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * @@ -119,7 +119,7 @@ find_pim6_nbr(source) * Set the iif, upstream router, preference and metric for the route * toward the source. Return TRUE is the route was found, othewise FALSE. * If srctype==PIM_IIF_SOURCE and if the source is directly connected - * then the "upstream" is set to NULL. + * then the "upstream" is set to NULL. * Note that srctype is a hold-over from the PIM-SM daemon and is unused. */ int @@ -134,7 +134,7 @@ set_incoming(srcentry_ptr, srctype) register pim_nbr_entry_t *n; /* Preference will be 0 if directly connected */ - srcentry_ptr->preference = 0; + srcentry_ptr->preference = 0; srcentry_ptr->metric = 0; if ((srcentry_ptr->incoming = local_address(source)) != NO_VIF) { @@ -160,7 +160,7 @@ set_incoming(srcentry_ptr, srctype) neighbor_addr = &rpfc.rpfneighbor; } else { - /* The source is directly connected. + /* The source is directly connected. */ srcentry_ptr->upstream = (pim_nbr_entry_t *)NULL; return (TRUE); @@ -193,13 +193,13 @@ set_incoming(srcentry_ptr, srctype) } else break; } - + /* TODO: control the number of messages! */ log(LOG_INFO, 0, "For src %s, iif is %d, next hop router is %s: NOT A PIM ROUTER", inet6_fmt(&source->sin6_addr), srcentry_ptr->incoming, inet6_fmt(&neighbor_addr->sin6_addr)); - srcentry_ptr->upstream = (pim_nbr_entry_t *)NULL; + srcentry_ptr->upstream = (pim_nbr_entry_t *)NULL; return(FALSE); } @@ -211,10 +211,10 @@ void set_leaves(mrtentry_ptr) { vifi_t vifi; struct uvif *v; - + /* Check for a group report on each vif */ - for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) - if(check_multicast_listener(v, &mrtentry_ptr->group->group)) + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) + if(check_multicast_listener(v, &mrtentry_ptr->group->group)) IF_SET(vifi, &mrtentry_ptr->leaves); } @@ -245,21 +245,21 @@ add_leaf(vifi, source, group) mrtentry_srcs = mrtentry_srcs->grpnext) { /* if applicable, add the vif to the leaves */ - if (mrtentry_srcs->incoming == vifi) + if (mrtentry_srcs->incoming == vifi) continue; if(!(IF_ISSET(vifi, &mrtentry_srcs->leaves))) { IF_DEBUG(DEBUG_MRT) - log(LOG_DEBUG, 0, "Adding leaf vif %d for src %s group %s", + log(LOG_DEBUG, 0, "Adding leaf vif %d for src %s group %s", vifi, inet6_fmt(&mrtentry_srcs->source->address.sin6_addr), inet6_fmt(&group->sin6_addr)); IF_COPY(&mrtentry_srcs->leaves, &new_leaves); IF_SET(vifi, &new_leaves); /* Add the leaf */ - - state_change = + + state_change = change_interfaces(mrtentry_srcs, mrtentry_srcs->incoming, &mrtentry_srcs->pruned_oifs, @@ -267,7 +267,7 @@ add_leaf(vifi, source, group) &mrtentry_srcs->asserted_oifs); /* Handle transition from negative cache */ - if(state_change == 1) + if(state_change == 1) trigger_join_alert(mrtentry_srcs); } } @@ -306,7 +306,7 @@ delete_leaf(vifi, source, group) mrtentry_srcs = mrtentry_srcs->grpnext) { /* if applicable, delete the vif from the leaves */ - if (mrtentry_srcs->incoming == vifi) + if (mrtentry_srcs->incoming == vifi) continue; if(IF_ISSET(vifi, &mrtentry_srcs->leaves)) { @@ -314,13 +314,13 @@ delete_leaf(vifi, source, group) IF_DEBUG(DEBUG_MRT) log(LOG_DEBUG, 0, "Deleting leaf vif %d for src %s, group %s", vifi, - inet6_fmt(&mrtentry_srcs->source->address.sin6_addr), + inet6_fmt(&mrtentry_srcs->source->address.sin6_addr), inet6_fmt(&group->sin6_addr)); - + IF_COPY(&mrtentry_srcs->leaves, &new_leaves); IF_CLR(vifi, &new_leaves); /* Remove the leaf */ - - state_change = + + state_change = change_interfaces(mrtentry_srcs, mrtentry_srcs->incoming, &mrtentry_srcs->pruned_oifs, @@ -344,7 +344,7 @@ calc_oifs(mrtentry_ptr, oifs_ptr) /* * oifs = * ((nbr_ifs - my_prune) + my_leaves) - my_filters - incoming_interface, - * i.e.`leaves` have higher priority than `prunes`, but lower than `filters'. + * i.e.`leaves` have higher priority than `prunes`, but lower than `filters'. * Asserted oifs (those that lost assert) are handled as pruned oifs. * The incoming interface is always deleted from the oifs */ @@ -353,7 +353,7 @@ calc_oifs(mrtentry_ptr, oifs_ptr) IF_ZERO(oifs_ptr); return; } - + IF_COPY(&nbr_mifs, &oifs); IF_CLR_MASK(&oifs, &mrtentry_ptr->pruned_oifs); IF_MERGE(&oifs, &mrtentry_ptr->leaves, &oifs); @@ -372,7 +372,7 @@ calc_oifs(mrtentry_ptr, oifs_ptr) * else return 0 * If the iif change or if the oifs change from NULL to non-NULL * or vice-versa, then schedule that mrtentry join/prune timer to - * timeout immediately. + * timeout immediately. */ int change_interfaces(mrtentry_ptr, new_iif, new_pruned_oifs, @@ -391,7 +391,7 @@ change_interfaces(mrtentry_ptr, new_iif, new_pruned_oifs, if_set old_asserted_oifs; /* unnecessary? */ vifi_t old_iif; int return_value; - + if (mrtentry_ptr == (mrtentry_t *)NULL) return (0); @@ -403,7 +403,7 @@ change_interfaces(mrtentry_ptr, new_iif, new_pruned_oifs, IF_COPY(&mrtentry_ptr->asserted_oifs, &old_asserted_oifs); IF_COPY(&mrtentry_ptr->oifs, &old_real_oifs); - + mrtentry_ptr->incoming = new_iif; IF_COPY(new_pruned_oifs, &mrtentry_ptr->pruned_oifs); IF_COPY(&new_leaves, &mrtentry_ptr->leaves); @@ -427,7 +427,7 @@ change_interfaces(mrtentry_ptr, new_iif, new_pruned_oifs, return 0; /* Nothing to change */ IF_COPY(&new_real_oifs, &mrtentry_ptr->oifs); - + k_chg_mfc(mld6_socket, &mrtentry_ptr->source->address, &mrtentry_ptr->group->group, new_iif, &new_real_oifs); @@ -437,7 +437,7 @@ change_interfaces(mrtentry_ptr, new_iif, new_pruned_oifs, return (return_value); } - + /* TODO: implement it. Required to allow changing of the physical interfaces * configuration without need to restart pimd. @@ -457,22 +457,22 @@ max_prune_timeout(mrtentry_ptr) vifi_t vifi; #if 0 /* XXX: I don't understand how the variable works...(jinmei@kame.net) */ - u_int16 time_left = 0; -#endif + u_int16 time_left = 0; +#endif u_int16 max_holdtime = 0; - for(vifi=0; vifi < numvifs; ++vifi) - if(IF_ISSET(vifi, &mrtentry_ptr->pruned_oifs) && - mrtentry_ptr->prune_timers[vifi]) + for(vifi=0; vifi < numvifs; ++vifi) + if(IF_ISSET(vifi, &mrtentry_ptr->pruned_oifs) && + mrtentry_ptr->prune_timers[vifi]) /* XXX - too expensive ? */ if(mrtentry_ptr->prune_timers[vifi] > max_holdtime) max_holdtime = mrtentry_ptr->prune_timers[vifi]; #if 0 /* XXX: This is original. But does it have any meaning? */ max_holdtime = time_left; -#endif +#endif - if(max_holdtime == 0) + if(max_holdtime == 0) max_holdtime = (u_int16)PIM_JOIN_PRUNE_HOLDTIME; return(max_holdtime); @@ -483,9 +483,9 @@ void process_kernel_call() { register struct mrt6msg *im; /* igmpmsg control struct */ - + im = (struct mrt6msg *) mld6_recv_buf; - + switch (im->im6_msgtype) { case MRT6MSG_NOCACHE: process_cache_miss(im); @@ -523,23 +523,23 @@ process_cache_miss(im) source.sin6_addr = im->im6_src; group.sin6_scope_id = inet6_uvif2scopeid(&group, &uvifs[im->im6_mif]); source.sin6_scope_id = inet6_uvif2scopeid(&source, &uvifs[im->im6_mif]); - + IF_DEBUG(DEBUG_MFC) log(LOG_DEBUG, 0, "Cache miss, src %s, dst %s", - inet6_fmt(&source.sin6_addr), inet6_fmt(&group.sin6_addr)); + inet6_fmt(&source.sin6_addr), inet6_fmt(&group.sin6_addr)); /* Don't create routing entries for the LAN scoped addresses */ if (IN6_IS_ADDR_MC_NODELOCAL(&group.sin6_addr) ||/* sanity? */ IN6_IS_ADDR_MC_LINKLOCAL(&group.sin6_addr)) - return; - + return; + /* Create the (S,G) entry */ mrtentry_ptr = find_route(&source, &group, MRTF_SG, CREATE); if (mrtentry_ptr == (mrtentry_t *)NULL) return; mrtentry_ptr->flags &= ~MRTF_NEW; - - /* Set oifs */ + + /* Set oifs */ set_leaves(mrtentry_ptr); calc_oifs(mrtentry_ptr, &(mrtentry_ptr->oifs)); @@ -560,7 +560,7 @@ process_cache_miss(im) /* * A multicast packet has been received on wrong iif by the kernel. * If the packet was received on a point-to-point interface, rate-limit - * prunes. if the packet was received on a LAN interface, rate-limit + * prunes. if the packet was received on a LAN interface, rate-limit * asserts. */ static void @@ -581,7 +581,7 @@ process_wrong_iif(im) /* PIMDM TODO Don't create routing entries for the LAN scoped addresses */ if (IN6_IS_ADDR_MC_NODELOCAL(&group.sin6_addr) ||/* sanity? */ IN6_IS_ADDR_MC_LINKLOCAL(&group.sin6_addr)) - return; + return; mrtentry_ptr = find_route(&source, &group, MRTF_SG, DONT_CREATE); if(mrtentry_ptr == (mrtentry_t *)NULL) @@ -599,14 +599,14 @@ process_wrong_iif(im) mrtentry_ptr->last_prune[mifi] = virtual_time; if(uvifs[mifi].uv_rmt_addr) - send_pim6_jp(mrtentry_ptr, PIM_ACTION_PRUNE, mifi, - uvifs[mifi].uv_rmt_addr, + send_pim6_jp(mrtentry_ptr, PIM_ACTION_PRUNE, mifi, + uvifs[mifi].uv_rmt_addr, max_prune_timeout(mrtentry_ptr), 0); - else - log(LOG_WARNING, 0, + else + log(LOG_WARNING, 0, "Can't send wrongvif prune on p2p %s: no remote address", uvifs[mifi].uv_lcl_addr); - } else + } else #endif { @@ -629,16 +629,16 @@ trigger_prune_alert(mrtentry_ptr) { IF_DEBUG(DEBUG_MRT) log(LOG_DEBUG, 0, "Now negative cache for src %s, grp %s - pruning", - inet6_fmt(&mrtentry_ptr->source->address.sin6_addr), + inet6_fmt(&mrtentry_ptr->source->address.sin6_addr), inet6_fmt(&mrtentry_ptr->group->group.sin6_addr)); /* Set the entry timer to the max of the prune timers */ SET_TIMER(mrtentry_ptr->timer, max_prune_timeout(mrtentry_ptr)); /* Send a prune */ - if(mrtentry_ptr->upstream) + if(mrtentry_ptr->upstream) send_pim6_jp(mrtentry_ptr, PIM_ACTION_PRUNE, mrtentry_ptr->incoming, - &mrtentry_ptr->upstream->address, + &mrtentry_ptr->upstream->address, max_prune_timeout(mrtentry_ptr), 0); } @@ -648,7 +648,7 @@ trigger_join_alert(mrtentry_ptr) { IF_DEBUG(DEBUG_MRT) log(LOG_DEBUG, 0, "Now forwarding state for src %s, grp %s - grafting", - inet6_fmt(&mrtentry_ptr->source->address.sin6_addr), + inet6_fmt(&mrtentry_ptr->source->address.sin6_addr), inet6_fmt(&mrtentry_ptr->group->group.sin6_addr)); /* Refresh the entry timer */ diff --git a/usr.sbin/pim6dd/routesock.c b/usr.sbin/pim6dd/routesock.c index bb2d59056a419..a2065b9674a53 100644 --- a/usr.sbin/pim6dd/routesock.c +++ b/usr.sbin/pim6dd/routesock.c @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,7 +31,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: routesock.c,v 1.4 1999/11/19 04:05:48 sumikawa Exp $ @@ -81,17 +81,17 @@ static int getmsg __P((register struct rt_msghdr *, int, * TODO: check again! */ #ifdef IRIX -#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \ +#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \ : sizeof(__uint64_t)) #else -#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ +#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ : sizeof(long)) #endif /* IRIX */ #ifdef HAVE_SA_LEN -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) #else -#define ADVANCE(x, n) (x += ROUNDUP(4)) /* TODO: a hack!! */ +#define ADVANCE(x, n) (x += ROUNDUP(4)) /* TODO: a hack!! */ #endif /* Open and initialize the routing socket */ @@ -111,7 +111,7 @@ init_routesock() #if 0 { int off; - + off = 0; if (setsockopt(routing_socket, SOL_SOCKET, SO_USELOOPBACK, (char *)&off, @@ -120,7 +120,7 @@ init_routesock() return -1; } } -#endif +#endif return 0; } @@ -137,22 +137,22 @@ k_req_incoming(source, rpfp) struct sockaddr_in6 *source; struct rpfctl *rpfp; { - int flags = RTF_STATIC; + int flags = RTF_STATIC; register sup su; static int seq; int rlen; register char *cp = m_rtmsg.m_space; register int l; struct rpfctl rpfinfo; - + /* TODO: a hack!!!! */ #ifdef HAVE_SA_LEN -#define NEXTADDR(w, u) \ +#define NEXTADDR(w, u) \ if (rtm_addrs & (w)) { \ l = ROUNDUP(u.sa.sa_len); bcopy((char *)&(u), cp, l); cp += l;\ } #else -#define NEXTADDR(w, u) \ +#define NEXTADDR(w, u) \ if (rtm_addrs & (w)) { \ l = ROUNDUP(4); bcopy((char *)&(u), cp, l); cp += l;\ } @@ -161,7 +161,7 @@ k_req_incoming(source, rpfp) /* initialize */ memset(&rpfp->rpfneighbor, 0, sizeof(rpfp->rpfneighbor)); rpfp->source = *source; - + /* check if local address or directly connected before calling the * routing socket */ @@ -169,7 +169,7 @@ k_req_incoming(source, rpfp) if ((rpfp->iif = find_vif_direct_local(source)) != NO_VIF) { rpfp->rpfneighbor = *source; return(TRUE); - } + } /* prepare the routing socket params */ rtm_addrs |= RTA_DST; @@ -191,7 +191,7 @@ k_req_incoming(source, rpfp) errno = 0; bzero((char *)&m_rtmsg, sizeof(m_rtmsg)); -#define rtm m_rtmsg.m_rtm +#define rtm m_rtmsg.m_rtm rtm.rtm_type = RTM_GET; rtm.rtm_flags = flags; rtm.rtm_version = RTM_VERSION; @@ -203,7 +203,7 @@ k_req_incoming(source, rpfp) NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_IFP, so_ifp); rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; - + if ((rlen = write(routing_socket, (char *)&m_rtmsg, l)) < 0) { IF_DEBUG(DEBUG_RPF | DEBUG_KERN) { if (errno == ESRCH) @@ -212,19 +212,19 @@ k_req_incoming(source, rpfp) else log(LOG_DEBUG, 0, "Error writing to routing socket"); } - return(FALSE); + return(FALSE); } - + do { l = read(routing_socket, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); - + if (l < 0) { IF_DEBUG(DEBUG_RPF | DEBUG_KERN) log(LOG_DEBUG, 0, "Read from routing socket failed: %s", strerror(errno)); return(FALSE); } - + if (getmsg(&rtm, l, &rpfinfo)){ rpfp->rpfneighbor = rpfinfo.rpfneighbor; rpfp->iif = rpfinfo.iif; @@ -237,7 +237,7 @@ k_req_incoming(source, rpfp) /* * Returns TRUE on success, FALSE otherwise. rpfinfo contains the result. */ -int +int getmsg(rtm, msglen, rpfinfop) register struct rt_msghdr *rtm; int msglen; @@ -252,10 +252,10 @@ getmsg(rtm, msglen, rpfinfop) vifi_t vifi; struct uvif *v; char in6txt[INET6_ADDRSTRLEN]; - + if (rpfinfop == (struct rpfctl *)NULL) return(FALSE); - + sin6 = (struct sockaddr_in6 *)&so_dst; IF_DEBUG(DEBUG_RPF) log(LOG_DEBUG, 0, "route to: %s", @@ -283,7 +283,7 @@ getmsg(rtm, msglen, rpfinfop) } ADVANCE(cp, sa); } - + if (!ifp){ /* No incoming interface */ IF_DEBUG(DEBUG_RPF) log(LOG_DEBUG, 0, @@ -320,18 +320,18 @@ getmsg(rtm, msglen, rpfinfop) rpfinfop->rpfneighbor.sin6_addr.s6_addr[3] = 0; } } - - for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) + + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) /* get the number of the interface by matching the name */ if ((strlen(v->uv_name) == ifp->sdl_nlen) && !(strncmp(v->uv_name,ifp->sdl_data,ifp->sdl_nlen))) break; - + IF_DEBUG(DEBUG_RPF) log(LOG_DEBUG, 0, " iif is %d", vifi); - + rpfinfop->iif = vifi; - + if (vifi >= numvifs){ IF_DEBUG(DEBUG_RPF) log(LOG_DEBUG, 0, @@ -339,7 +339,7 @@ getmsg(rtm, msglen, rpfinfop) inet_ntop(AF_INET6, &sin6->sin6_addr, in6txt, INET6_ADDRSTRLEN)); return(FALSE);/* invalid iif */ } - + return(TRUE); } @@ -361,7 +361,7 @@ k_req_incoming(source, rpfcinfo) rpfcinfo->iif = NO_VIF; /* just initialized, will be */ /* changed in kernel */ memset(&rpfcinfo->rpfneighbor, 0, sizeof(rpfcinfo->rpfneighbor)); /* initialized */ - + if (ioctl(udp_socket, SIOCGETRPF, (char *) rpfcinfo) < 0){ log(LOG_ERR, errno, "ioctl SIOCGETRPF k_req_incoming"); return(FALSE); diff --git a/usr.sbin/pim6dd/timer.c b/usr.sbin/pim6dd/timer.c index 410183ffb57e8..c1ebf32f74879 100644 --- a/usr.sbin/pim6dd/timer.c +++ b/usr.sbin/pim6dd/timer.c @@ -10,15 +10,15 @@ * documentation, and that any documentation, advertising materials, * and other materials related to such distribution and use acknowledge * that the software was developed by the University of Oregon. - * The name of the University of Oregon may not be used to endorse or - * promote products derived from this software without specific prior + * The name of the University of Oregon may not be used to endorse or + * promote products derived from this software without specific prior * written permission. * * THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -30,22 +30,22 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Kurt Windisch (kurtw@antc.uoregon.edu) * - * $Id: timer.c,v 1.3 1999/09/15 07:45:12 jinmei Exp $ + * $Id: timer.c,v 1.5 2000/05/18 16:09:39 itojun Exp $ */ /* * Part of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". - * + * * The pimd program is COPYRIGHT 1998 by University of Southern California. * * Part of this program has been derived from mrouted. * The mrouted program is covered by the license in the accompanying file * named "LICENSE.mrouted". - * + * * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * @@ -116,7 +116,7 @@ age_vifs() /* XXX: TODO: currently, sending to qe* interface which is DOWN * doesn't return error (ENETDOWN) on my Solaris machine, - * so have to check periodically the + * so have to check periodically the * interfaces status. If this is fixed, just remove the defs around * the "if (vifs_down)" line. */ @@ -130,6 +130,20 @@ age_vifs() for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN)) continue; + + /* Timeout the MLD querier (unless we re the querier) */ + if ((v->uv_flags & VIFF_QUERIER) == 0 && + v->uv_querier) { /* this must be non-NULL, but check for safety. */ + IF_TIMEOUT(v->uv_querier->al_timer) { + /* act as a querier by myself */ + v->uv_flags |= VIFF_QUERIER; + v->uv_querier->al_addr = v->uv_linklocal->pa_addr; + v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL; + time(&v->uv_querier->al_ctime); /* reset timestamp */ + query_groups(v); + } + } + /* Timeout neighbors */ for (curr_nbr = v->uv_pim_neighbors; curr_nbr != NULL; curr_nbr = next_nbr) { @@ -146,7 +160,7 @@ age_vifs() delete_pim6_nbr(curr_nbr); } - + /* PIM_HELLO periodic */ IF_TIMEOUT(v->uv_pim_hello_timer) send_pim6_hello(v, PIM_TIMER_HELLO_HOLDTIME); @@ -191,16 +205,16 @@ age_routes() ucast_flag = FALSE; } - /* Walk the the (S,G) entries */ - if(grplist == (grpentry_t *)NULL) + /* Walk the (S,G) entries */ + if(grplist == (grpentry_t *)NULL) return; for(grpentry_ptr = grplist; - grpentry_ptr != (grpentry_t *)NULL; + grpentry_ptr != (grpentry_t *)NULL; grpentry_ptr = grpentry_next) { grpentry_next = grpentry_ptr->next; - for(mrtentry_ptr = grpentry_ptr->mrtlink; - mrtentry_ptr != (mrtentry_t *)NULL; + for(mrtentry_ptr = grpentry_ptr->mrtlink; + mrtentry_ptr != (mrtentry_t *)NULL; mrtentry_ptr = mrtentry_next) { mrtentry_next = mrtentry_ptr->grpnext; @@ -214,21 +228,21 @@ age_routes() delete_mrtentry(mrtentry_ptr); continue; } - if(!(IF_ISEMPTY(&mrtentry_ptr->oifs)) && + if(!(IF_ISEMPTY(&mrtentry_ptr->oifs)) && curr_bytecnt != mrtentry_ptr->sg_count.bytecnt) { /* Packets have been forwarded - refresh timer - * Note that these counters count packets received, + * Note that these counters count packets received, * not packets forwarded. So only refresh if packets * received and non-null oiflist. */ IF_DEBUG(DEBUG_MFC) - log(LOG_DEBUG, 0, + log(LOG_DEBUG, 0, "Refreshing src %s, dst %s after %d bytes forwarded", inet6_fmt(&mrtentry_ptr->source->address.sin6_addr), inet6_fmt(&mrtentry_ptr->group->group.sin6_addr), - mrtentry_ptr->sg_count.bytecnt); + mrtentry_ptr->sg_count.bytecnt); SET_TIMER(mrtentry_ptr->timer, PIM_DATA_TIMEOUT); - } + } /* Time out the entry */ IF_TIMEOUT(mrtentry_ptr->timer) { @@ -237,7 +251,7 @@ age_routes() } /* Time out asserts */ - if(mrtentry_ptr->flags & MRTF_ASSERTED) + if(mrtentry_ptr->flags & MRTF_ASSERTED) IF_TIMEOUT(mrtentry_ptr->assert_timer) { mrtentry_ptr->flags &= ~MRTF_ASSERTED; mrtentry_ptr->upstream = mrtentry_ptr->source->upstream; @@ -255,7 +269,7 @@ age_routes() change_flag = TRUE; } } - + /* Unicast Route changes */ update_src_iif = FALSE; if (ucast_flag == TRUE) { @@ -264,7 +278,7 @@ age_routes() srcentry_save.upstream = mrtentry_ptr->source->upstream; srcentry_save.preference = mrtentry_ptr->source->preference; srcentry_save.metric = mrtentry_ptr->source->metric; - + if (set_incoming(mrtentry_ptr->source, PIM_IIF_SOURCE) != TRUE) { /* @@ -277,7 +291,7 @@ age_routes() } else { /* iif info found */ - if (!(mrtentry_ptr->flags & MRTF_ASSERTED) && + if (!(mrtentry_ptr->flags & MRTF_ASSERTED) && ((srcentry_save.incoming != mrtentry_ptr->incoming) || (srcentry_save.upstream != @@ -294,9 +308,9 @@ age_routes() * larger and thus the correct assert winner * from upstream will be chosen. */ - mrtentry_ptr->preference = + mrtentry_ptr->preference = mrtentry_ptr->source->preference; - mrtentry_ptr->metric = + mrtentry_ptr->metric = mrtentry_ptr->source->metric; } } @@ -304,7 +318,7 @@ age_routes() if ((change_flag == TRUE) || (update_src_iif == TRUE)) { /* Flush the changes */ - state_change = + state_change = change_interfaces(mrtentry_ptr, mrtentry_ptr->incoming, &mrtentry_ptr->pruned_oifs, diff --git a/usr.sbin/pim6dd/trace.c b/usr.sbin/pim6dd/trace.c index 1556097e154a5..7d1f641a79711 100644 --- a/usr.sbin/pim6dd/trace.c +++ b/usr.sbin/pim6dd/trace.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -47,7 +47,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -59,7 +59,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: trace.c,v 1.5 1999/09/16 08:46:00 jinmei Exp $ @@ -113,7 +113,7 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) struct sockaddr_in6 *sa_global; #ifdef SM_ONLY rpentry_t *rpentry_ptr; -#endif +#endif /* Remember qid across invocations */ static u_int32 oqid = 0; @@ -202,9 +202,9 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) } else log(LOG_DEBUG, 0, "...no route"); } - + /* - * Query type packet - check if rte exists + * Query type packet - check if rte exists * Check if the query destination is a vif connected to me. * and if so, whether I should start response back */ @@ -238,7 +238,7 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) #endif } vifi = find_vif_direct(&dst_sa6); - + if (vifi == NO_VIF) { /* * The traceroute destination is not on one of @@ -276,21 +276,21 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) "Wrong interface for packet"); errcode = TR_WRONG_IF; } - } - + } + /* Now that we've decided to send a response, save the qid */ oqid = qry->tr_qid; IF_DEBUG(DEBUG_TRACE) log(LOG_DEBUG, 0, "Sending traceroute response"); - + /* copy the packet to the sending buffer */ p = mld6_send_buf + sizeof(struct mld6_hdr); - + bcopy(data, p, datalen); - + p += datalen; - + /* * If there is no room to insert our reply, coopt the previous hop * error indication to relay this fact. @@ -309,7 +309,7 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) bzero(resp, sizeof(struct tr6_resp)); datalen += (RLEN + sizeof(struct mld6_hdr)); - resp->tr_qarr = htonl(((tp.tv_sec + JAN_1970) << 16) + + resp->tr_qarr = htonl(((tp.tv_sec + JAN_1970) << 16) + ((tp.tv_usec << 10) / 15625)); resp->tr_rproto = PROTO_PIM; @@ -532,7 +532,7 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) "reply" : "request on", inet6_fmt(dst), sa6 ? inet6_fmt(&sa6->sin6_addr) : "unspecified"); - + send_mld6(resptype, no, sa6, &resp_sa6, group, ifindex, 0, datalen, 0); } diff --git a/usr.sbin/pim6dd/trace.h b/usr.sbin/pim6dd/trace.h index 31e79c7274f32..739c987e16d42 100644 --- a/usr.sbin/pim6dd/trace.h +++ b/usr.sbin/pim6dd/trace.h @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -47,7 +47,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -59,7 +59,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: trace.h,v 1.2 1999/09/12 17:00:10 jinmei Exp $ @@ -96,8 +96,8 @@ struct tr6_query { #endif /* BYTE_ORDER */ }; -#define tr_rhlim q.rhlim -#define tr_qid q.qid +#define tr_rhlim q.rhlim +#define tr_qid q.qid /* * Traceroute response format. A traceroute response has a tr_query at the @@ -126,60 +126,60 @@ struct tr6_resp { }; /* defs within mtrace */ -#define QUERY 1 -#define RESP 2 -#define QLEN sizeof(struct tr6_query) -#define RLEN sizeof(struct tr6_resp) +#define QUERY 1 +#define RESP 2 +#define QLEN sizeof(struct tr6_query) +#define RLEN sizeof(struct tr6_resp) /* fields for tr_inifid and tr_outifid */ -#define TR_NO_VIF 0xffffffff/* interface can't be determined */ +#define TR_NO_VIF 0xffffffff/* interface can't be determined */ /* fields for tr_rflags (forwarding error codes) */ -#define TR_NO_ERR 0 /* No error */ -#define TR_WRONG_IF 1 /* traceroute arrived on non-oif */ -#define TR_PRUNED 2 /* router has sent a prune upstream */ -#define TR_OPRUNED 3 /* stop forw. after request from next hop rtr*/ -#define TR_SCOPED 4 /* group adm. scoped at this hop */ -#define TR_NO_RTE 5 /* no route for the source */ -#define TR_NO_LHR 6 /* not the last-hop router */ -#define TR_NO_FWD 7 /* not forwarding for this (S,G). Reason = ? */ -#define TR_RP 8 /* I am the RP/Core */ -#define TR_IIF 9 /* request arrived on the iif */ -#define TR_NO_MULTI 0x0a /* multicast disabled on that interface */ -#define TR_NO_SPACE 0x81 /* no space to insert responce data block */ -#define TR_OLD_ROUTER 0x82 /* previous hop does not support traceroute */ -#define TR_ADMIN_PROHIB 0x83 /* traceroute adm. prohibited */ +#define TR_NO_ERR 0 /* No error */ +#define TR_WRONG_IF 1 /* traceroute arrived on non-oif */ +#define TR_PRUNED 2 /* router has sent a prune upstream */ +#define TR_OPRUNED 3 /* stop forw. after request from next hop rtr*/ +#define TR_SCOPED 4 /* group adm. scoped at this hop */ +#define TR_NO_RTE 5 /* no route for the source */ +#define TR_NO_LHR 6 /* not the last-hop router */ +#define TR_NO_FWD 7 /* not forwarding for this (S,G). Reason = ? */ +#define TR_RP 8 /* I am the RP/Core */ +#define TR_IIF 9 /* request arrived on the iif */ +#define TR_NO_MULTI 0x0a /* multicast disabled on that interface */ +#define TR_NO_SPACE 0x81 /* no space to insert responce data block */ +#define TR_OLD_ROUTER 0x82 /* previous hop does not support traceroute */ +#define TR_ADMIN_PROHIB 0x83 /* traceroute adm. prohibited */ /* fields for tr_flags */ -#define TR_SUBNET_COUNT 0x80 /* pkt count for (S,G) is for source network */ +#define TR_SUBNET_COUNT 0x80 /* pkt count for (S,G) is for source network */ /* fields for r_plen */ -#define TR_GROUP_ONLY 0xff /* forwarding solely on group state */ +#define TR_GROUP_ONLY 0xff /* forwarding solely on group state */ /* fields for packets count */ -#define TR_CANT_COUNT 0xffffffff /* no count can be reported */ +#define TR_CANT_COUNT 0xffffffff /* no count can be reported */ /* fields for tr_rproto (routing protocol) */ -#define PROTO_DVMRP 1 -#define PROTO_MOSPF 2 -#define PROTO_PIM 3 -#define PROTO_CBT 4 -#define PROTO_PIM_SPECIAL 5 -#define PROTO_PIM_STATIC 6 -#define PROTO_DVMRP_STATIC 7 +#define PROTO_DVMRP 1 +#define PROTO_MOSPF 2 +#define PROTO_PIM 3 +#define PROTO_CBT 4 +#define PROTO_PIM_SPECIAL 5 +#define PROTO_PIM_STATIC 6 +#define PROTO_DVMRP_STATIC 7 -#define MASK_TO_VAL(x, i) { \ +#define MASK_TO_VAL(x, i) { \ u_int32_t _x = ntohl(x); \ (i) = 1; \ while ((_x) <<= 1) \ (i)++; \ }; -#define VAL_TO_MASK(x, i) { \ +#define VAL_TO_MASK(x, i) { \ x = htonl(~((1 << (32 - (i))) - 1)); \ }; -#define MASKLEN_TO_MASK6(masklen, mask6) \ +#define MASKLEN_TO_MASK6(masklen, mask6) \ do {\ u_char maskarray[8] = \ {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; \ @@ -195,10 +195,10 @@ struct tr6_resp { /* obnoxious gcc gives an extraneous warning about this constant... */ #if defined(__STDC__) || defined(__GNUC__) -#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ +#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ #else -#define JAN_1970 2208988800L /* 1970 - 1900 in seconds */ -#define const /**/ +#define JAN_1970 2208988800L /* 1970 - 1900 in seconds */ +#define const /**/ #endif -#define NBR_VERS(n) (((n)->al_pv << 8) + (n)->al_mv) +#define NBR_VERS(n) (((n)->al_pv << 8) + (n)->al_mv) diff --git a/usr.sbin/pim6dd/vif.c b/usr.sbin/pim6dd/vif.c index 55bdb1fca8a7e..2fa533c641138 100644 --- a/usr.sbin/pim6dd/vif.c +++ b/usr.sbin/pim6dd/vif.c @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,10 +31,10 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * - * $Id: vif.c,v 1.3 1999/09/12 17:00:11 jinmei Exp $ + * $Id: vif.c,v 1.5 2000/05/18 15:29:40 itojun Exp $ */ /* * Part of this program has been derived from mrouted. @@ -83,7 +83,7 @@ init_vifs() vifi_t vifi; struct uvif *v; int enabled_vifs; - + numvifs = 0; vifs_down = FALSE; @@ -137,7 +137,7 @@ init_vifs() */ enabled_vifs = 0; phys_vif = -1; - + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN)) continue; @@ -184,11 +184,11 @@ start_all_vifs() if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN)) { if (v->uv_flags & VIFF_DISABLED) log(LOG_INFO, 0, - "%s is DISABLED; if #%u out of service", + "%s is DISABLED; if #%u out of service", v->uv_name, vifi); else log(LOG_INFO, 0, - "%s is DOWN; if #%u out of service", + "%s is DOWN; if #%u out of service", v->uv_name, vifi); } else @@ -220,7 +220,7 @@ stop_all_vifs() * physical, tunnel (tunnels will be used in the future * when this code becomes PIM multicast boarder router.) */ -static void +static void start_vif(vifi) vifi_t vifi; { @@ -234,29 +234,36 @@ start_vif(vifi) /* TODO: CHECK THE TIMERS!!!!! Set or reset? */ v->uv_gq_timer = 0; v->uv_pim_neighbors = (pim_nbr_entry_t *)NULL; - + /* Tell kernel to add, i.e. start this vif */ - k_add_vif(mld6_socket, vifi, &uvifs[vifi]); + k_add_vif(mld6_socket, vifi, &uvifs[vifi]); log(LOG_INFO, 0, "%s comes up; if #%u now in service", v->uv_name, vifi); - + /* * Join the PIM multicast group on the interface. */ k_join(mld6_socket, &allpim6routers_group.sin6_addr, v->uv_ifindex); - + /* * Join the ALL-ROUTERS multicast group on the interface. * This allows mtrace requests to loop back if they are run * on the multicast router. */ k_join(mld6_socket, &allrouters_group.sin6_addr, v->uv_ifindex); - + /* * Until neighbors are discovered, assume responsibility for sending * periodic group membership queries to the subnet. Send the first * query. */ v->uv_flags |= VIFF_QUERIER; + if (!v->uv_querier) { + v->uv_querier = (struct listaddr *)malloc(sizeof(*v->uv_querier)); + memset(v->uv_querier, 0, sizeof(*v->uv_querier)); + } + v->uv_querier->al_addr = v->uv_linklocal->pa_addr; + v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL; + time(&v->uv_querier->al_ctime); /* reset timestamp */ query_groups(v); /* @@ -272,7 +279,7 @@ start_vif(vifi) * Stop a vif (either physical interface or tunnel). * If we are running only PIM we don't have tunnels. */ -static void +static void stop_vif(vifi) vifi_t vifi; { @@ -280,11 +287,11 @@ stop_vif(vifi) struct listaddr *a; register pim_nbr_entry_t *n, *next; struct vif_acl *acl; - + /* - * TODO: make sure that the kernel viftable is + * TODO: make sure that the kernel viftable is * consistent with the daemon table - */ + */ v = &uvifs[vifi]; k_leave(mld6_socket, &allpim6routers_group.sin6_addr, v->uv_ifindex); k_leave(mld6_socket, &allrouters_group.sin6_addr, v->uv_ifindex); @@ -297,15 +304,15 @@ stop_vif(vifi) v->uv_groups = a->al_next; free((char *)a); } - + /* * TODO: inform (eventually) the neighbors I am going down by sending * PIM_HELLO with holdtime=0 so someone else should become a DR. - */ + */ /* TODO: dummy! Implement it!! Any problems if don't use it? */ delete_vif_from_mrt(vifi); - + /* * Delete the interface from the kernel's vif structure. */ @@ -331,7 +338,7 @@ stop_vif(vifi) vifs_down = TRUE; log(LOG_INFO, 0, "%s goes down; if #%u out of service", v->uv_name, vifi); -} +} /* * return the max global Ipv6 address of an UP and ENABLED interface @@ -368,7 +375,7 @@ max_global_address() &p->pa_addr) && !IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr) && !IN6_IS_ADDR_SITELOCAL(&p->pa_addr.sin6_addr)) - pmax=p; + pmax=p; } } } @@ -422,7 +429,7 @@ check_vif_state() for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (v->uv_flags & VIFF_DISABLED) continue; - + strncpy(ifr.ifr_name, v->uv_name, IFNAMSIZ); /* get the interface flags */ if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ifr) < 0) @@ -455,14 +462,14 @@ check_vif_state() * Local addresses are excluded. * Return the vif number or NO_VIF if not found. */ -vifi_t +vifi_t find_vif_direct(src) struct sockaddr_in6 *src; { vifi_t vifi; register struct uvif *v; register struct phaddr *p; - + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | VIFF_TUNNEL)) continue; @@ -474,7 +481,7 @@ find_vif_direct(src) } } return (NO_VIF); -} +} /* @@ -488,7 +495,7 @@ local_address(src) vifi_t vifi; register struct uvif *v; register struct phaddr *p; - + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN)) continue; @@ -496,9 +503,9 @@ local_address(src) if (inet6_equal(src, &p->pa_addr)) return(vifi); } - } + } /* Returning NO_VIF means not a local address */ - return (NO_VIF); + return (NO_VIF); } /* @@ -507,14 +514,14 @@ local_address(src) * (tunnels excluded). * Return the vif number or NO_VIF if not found. */ -vifi_t +vifi_t find_vif_direct_local(src) struct sockaddr_in6 *src; { vifi_t vifi; register struct uvif *v; register struct phaddr *p; - + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | VIFF_TUNNEL)) continue; @@ -525,4 +532,4 @@ find_vif_direct_local(src) } } return (NO_VIF); -} +} diff --git a/usr.sbin/pim6dd/vif.h b/usr.sbin/pim6dd/vif.h index 8dd44fc06dd65..2a068e32dcc05 100644 --- a/usr.sbin/pim6dd/vif.h +++ b/usr.sbin/pim6dd/vif.h @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,7 +31,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: vif.h,v 1.2 1999/08/24 16:45:23 jinmei Exp $ @@ -65,9 +65,9 @@ typedef u_int32 vifbitmap_t; #define VIFM_SET(n, m) ((m) |= (1 << (n))) #define VIFM_CLR(n, m) ((m) &= ~(1 << (n))) #define VIFM_ISSET(n, m) ((m) & (1 << (n))) -#define VIFM_CLRALL(m) ((m) = 0x00000000) -#define VIFM_COPY(mfrom, mto) ((mto) = (mfrom)) -#define VIFM_SAME(m1, m2) ((m1) == (m2)) +#define VIFM_CLRALL(m) ((m) = 0x00000000) +#define VIFM_COPY(mfrom, mto) ((mto) = (mfrom)) +#define VIFM_SAME(m1, m2) ((m1) == (m2)) #endif /* * And <netinet/ip_mroute.h> was missing some required functions anyway @@ -79,31 +79,31 @@ typedef u_int32 vifbitmap_t; #define VIFM_ISEMPTY(m) ((m) == 0) #define VIFM_CLR_MASK(m, mask) ((m) &= ~(mask)) #define VIFM_SET_MASK(m, mask) ((m) |= (mask)) -#define VIFM_MERGE(m1, m2, result) ((result) = (m1) | (m2)) +#define VIFM_MERGE(m1, m2, result) ((result) = (m1) | (m2)) /* * And <netinet6/ip6_mroute.h> was missing some required functions anyway */ extern if_set if_nullset; -#define IF_ISEMPTY(p) (memcmp((p), &if_nullset, sizeof(if_nullset)) == 0) -#define IF_CLR_MASK(p, mask) \ +#define IF_ISEMPTY(p) (memcmp((p), &if_nullset, sizeof(if_nullset)) == 0) +#define IF_CLR_MASK(p, mask) \ {\ int idx;\ for (idx = 0; idx < sizeof(*(p))/sizeof(fd_mask); idx++) {\ (p)->ifs_bits[idx] &= ~((mask)->ifs_bits[idx]);\ }\ } -#define IF_MERGE(p1, p2, result) \ +#define IF_MERGE(p1, p2, result) \ {\ int idx;\ for (idx = 0; idx < sizeof(*(p1))/sizeof(fd_mask); idx++) {\ (result)->ifs_bits[idx] = (p1)->ifs_bits[idx]|(p2)->ifs_bits[idx]; \ }\ } -#define IF_SAME(p1, p2) (memcmp((p1),(p2),sizeof(*(p1))) == 0) +#define IF_SAME(p1, p2) (memcmp((p1),(p2),sizeof(*(p1))) == 0) /* Check whether I am the forwarder on some LAN */ -#define VIFM_FORWARDER(leaves, oifs) ((leaves) & (oifs)) +#define VIFM_FORWARDER(leaves, oifs) ((leaves) & (oifs)) /* * Neighbor bitmaps are, for efficiency, implemented as a struct @@ -111,7 +111,7 @@ extern if_set if_nullset; * have a native type that's bigger than a long, define it below. */ #define NBRTYPE u_long -#define NBRBITS sizeof(NBRTYPE) * 8 +#define NBRBITS sizeof(NBRTYPE) * 8 typedef struct { NBRTYPE hi; @@ -153,8 +153,8 @@ typedef struct { * (called a "phyint"), a virtual point-to-point link (called a "tunnel") * or a "register vif" used by PIM. The register vif is used by the * Designated Router (DR) to send encapsulated data packets to the - * Rendevous Point (RP) for a particular group. The data packets are - * encapsulated in PIM messages (IPPROTO_PIM = 103) and then unicast to + * Rendevous Point (RP) for a particular group. The data packets are + * encapsulated in PIM messages (IPPROTO_PIM = 103) and then unicast to * the RP. * (Note: all addresses, subnet numbers and masks are kept in NETWORK order.) */ @@ -164,13 +164,13 @@ struct uvif { u_char uv_admetric; /* advertised cost of this vif */ #if 0 /* unused for IPv6? */ u_char uv_threshold; /* min ttl required to forward on vif */ -#endif +#endif u_int uv_rate_limit; /* rate limit on this vif */ struct sockaddr_in6 uv_lcl_addr;/* local address of this vif */ struct phaddr *uv_linklocal;/* link-local address of this vif */ #if 0 u_int32 uv_rmt_addr; /* remote end-point addr (tunnels only) */ -#endif +#endif struct sockaddr_in6 uv_dst_addr; /* destination for PIM messages */ struct sockaddr_in6 uv_prefix; /* prefix (phyints only) */ struct in6_addr uv_subnetmask; /* subnet mask (phyints only) */ @@ -194,24 +194,24 @@ struct uvif { }; /* TODO: define VIFF_KERNEL_FLAGS */ -#define VIFF_KERNEL_FLAGS (VIFF_TUNNEL | VIFF_SRCRT) -#define VIFF_DOWN 0x000100 /* kernel state of interface */ -#define VIFF_DISABLED 0x000200 /* administratively disabled */ -#define VIFF_QUERIER 0x000400 /* I am the subnet's querier */ -#define VIFF_ONEWAY 0x000800 /* Maybe one way interface */ -#define VIFF_LEAF 0x001000 /* all neighbors are leaves */ -#define VIFF_IGMPV1 0x002000 /* Act as an IGMPv1 Router */ +#define VIFF_KERNEL_FLAGS (VIFF_TUNNEL | VIFF_SRCRT) +#define VIFF_DOWN 0x000100 /* kernel state of interface */ +#define VIFF_DISABLED 0x000200 /* administratively disabled */ +#define VIFF_QUERIER 0x000400 /* I am the subnet's querier */ +#define VIFF_ONEWAY 0x000800 /* Maybe one way interface */ +#define VIFF_LEAF 0x001000 /* all neighbors are leaves */ +#define VIFF_IGMPV1 0x002000 /* Act as an IGMPv1 Router */ #define VIFF_REXMIT_PRUNES 0x004000 /* retransmit prunes */ -#define VIFF_PASSIVE 0x008000 /* passive tunnel */ +#define VIFF_PASSIVE 0x008000 /* passive tunnel */ #define VIFF_ALLOW_NONPRUNERS 0x010000 /* ok to peer with nonprunrs */ -#define VIFF_NOFLOOD 0x020000 /* don't flood on this vif */ +#define VIFF_NOFLOOD 0x020000 /* don't flood on this vif */ #define VIFF_DR 0x040000 /* designated router */ /* TODO: VIFF_NONBRS == VIFF_ONEWAY? */ #define VIFF_NONBRS 0x080000 /* no neighbor on vif */ -#define VIFF_POINT_TO_POINT 0x100000 /* point-to-point link */ -#define VIFF_PIM_NBR 0x200000 /* PIM neighbor */ -#define VIFF_DVMRP_NBR 0x400000 /* DVMRP neighbor */ -#define VIFF_NOLISTENER 0x800000 /* no listener on the link */ +#define VIFF_POINT_TO_POINT 0x100000 /* point-to-point link */ +#define VIFF_PIM_NBR 0x200000 /* PIM neighbor */ +#define VIFF_DVMRP_NBR 0x400000 /* DVMRP neighbor */ +#define VIFF_NOLISTENER 0x800000 /* no listener on the link */ struct phaddr { struct phaddr *pa_next; @@ -278,12 +278,12 @@ struct listaddr { #define NBRF_DONTPEER (NBRF_WAITING|NBRF_ONEWAY|NBRF_TOOOLD| \ NBRF_TOOMANYROUTES|NBRF_NOTPRUNING) -#define NO_VIF ((vifi_t)MAXMIFS) /* An invalid vif index */ - +#define NO_VIF ((vifi_t)MAXMIFS) /* An invalid vif index */ + /* * Used to get the RPF neighbor and IIF info - * for a given source from the unicast routing table. + * for a given source from the unicast routing table. */ struct rpfctl { struct sockaddr_in6 source; /* the source for which we want iif and rpfnbr */ diff --git a/usr.sbin/pim6sd/BUGS.TODO b/usr.sbin/pim6sd/BUGS.TODO index 4a9e684366399..93c330e5aeef4 100644 --- a/usr.sbin/pim6sd/BUGS.TODO +++ b/usr.sbin/pim6sd/BUGS.TODO @@ -1,7 +1,7 @@ $Id: BUGS.TODO,v 1.1.1.1 1999/08/08 23:30:57 itojun Exp $ $FreeBSD$ -THIS LIST IS FAR AWAY FROM BEING COMPLETE, so these are the few things +THIS LIST IS FAR AWAY FROM BEING COMPLETE, so these are the few things that came up at the right moment to be written down. * Experimental kernel MFC (*,G) related: @@ -24,12 +24,12 @@ that came up at the right moment to be written down. * Use NetBSD's definition for IPADDR (netinet/in.h): #ifdef _KERNEL -#define __IPADDR(x) ((u_int32_t) htonl((u_int32_t)(x))) +#define __IPADDR(x) ((u_int32_t) htonl((u_int32_t)(x))) #else -#define __IPADDR(x) ((u_int32_t)(x)) +#define __IPADDR(x) ((u_int32_t)(x)) #endif - + * The (S,G)RPbit in the DR for the sender and the (S,G)SPT in the downstream router won't timeout and will refresh each other even if the sender is not active: @@ -57,12 +57,12 @@ that came up at the right moment to be written down. same host as the RP for the multicast group (probably was fixed with alpha6, because I cannot reproduce it anymore) - * Do more precise error check for the received PIM messages. In most cases, + * Do more precise error check for the received PIM messages. In most cases, the whole message must be parsed completely before starting processing it. * Clean up the debugging messages. - * Use Patricia tree to search the routing table + * Use Patricia tree to search the routing table (There is a nice paper in Sigcomm '97 about fast routing tables implementation, so need to check it as well) @@ -86,7 +86,7 @@ that came up at the right moment to be written down. * Send Initial_Reply RSRR message if the interfaces detected by pimd change - * SNMP support + * SNMP support ===TODO by function name=== igmp_proto.c: diff --git a/usr.sbin/pim6sd/BUGS.V6 b/usr.sbin/pim6sd/BUGS.V6 index cdc1903ec8ded..330ffdad3aca4 100644 --- a/usr.sbin/pim6sd/BUGS.V6 +++ b/usr.sbin/pim6sd/BUGS.V6 @@ -1,4 +1,4 @@ - $FreeBSD$ +$FreeBSD$ Write your bugs reports here diff --git a/usr.sbin/pim6sd/LICENSE.mrouted b/usr.sbin/pim6sd/LICENSE.mrouted index 9cf01b69aca45..e03eb82afbdff 100644 --- a/usr.sbin/pim6sd/LICENSE.mrouted +++ b/usr.sbin/pim6sd/LICENSE.mrouted @@ -1,4 +1,4 @@ - $FreeBSD$ +$FreeBSD$ The mrouted program is covered by the following license. Use of the mrouted program represents acceptance of these terms and conditions. diff --git a/usr.sbin/pim6sd/LICENSE.pim6dd b/usr.sbin/pim6sd/LICENSE.pim6dd index 0055e6ecf1c6b..764c6fda4c399 100644 --- a/usr.sbin/pim6sd/LICENSE.pim6dd +++ b/usr.sbin/pim6sd/LICENSE.pim6dd @@ -29,4 +29,3 @@ * $FreeBSD$ */ - diff --git a/usr.sbin/pim6sd/LICENSE.pim6sd b/usr.sbin/pim6sd/LICENSE.pim6sd index 853f9e09930cb..3f96a5526c99b 100644 --- a/usr.sbin/pim6sd/LICENSE.pim6sd +++ b/usr.sbin/pim6sd/LICENSE.pim6sd @@ -28,7 +28,7 @@ */ /* * Questions concerning this software should be directed to - * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg. + * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg. * * $FreeBSD$ */ diff --git a/usr.sbin/pim6sd/LICENSE.pimd b/usr.sbin/pim6sd/LICENSE.pimd index 96791e5363d23..46955e157457c 100644 --- a/usr.sbin/pim6sd/LICENSE.pimd +++ b/usr.sbin/pim6sd/LICENSE.pimd @@ -19,7 +19,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -31,7 +31,7 @@ * noted when applicable. */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: LICENSE.pimd,v 1.1.1.1 1999/08/08 23:30:57 itojun Exp $ diff --git a/usr.sbin/pim6sd/Makefile b/usr.sbin/pim6sd/Makefile index d37c5638fce12..905321cb5b469 100644 --- a/usr.sbin/pim6sd/Makefile +++ b/usr.sbin/pim6sd/Makefile @@ -11,7 +11,7 @@ # 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 @@ -23,6 +23,56 @@ # 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. + +# Copyright (c) 1998 by the University of Oregon. +# All rights reserved. +# +# Permission to use, copy, modify, and distribute this software and +# its documentation in source and binary forms for lawful +# purposes and without fee is hereby granted, provided +# that the above copyright notice appear in all copies and that both +# the copyright notice and this permission notice appear in supporting +# documentation, and that any documentation, advertising materials, +# and other materials related to such distribution and use acknowledge +# that the software was developed by the University of Oregon. +# The name of the University of Oregon may not be used to endorse or +# promote products derived from this software without specific prior +# written permission. +# +# THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS +# ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND +# NON-INFRINGEMENT. +# +# IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY +# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, +# TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, +# THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# Other copyrights might apply to parts of this software and are so +# noted when applicable. +# +# +# Questions concerning this software should be directed to +# Kurt Windisch (kurtw@antc.uoregon.edu) +# +# $Id: Makefile,v 1.8 2000/02/25 06:32:22 itojun Exp $ +# +# +#Part of this program has been derived from PIM sparse-mode pimd. +#The pimd program is covered by the license in the accompanying file +#named "LICENSE.pimd". +# +#The pimd program is COPYRIGHT 1998 by University of Southern California. +# +#Part of this program has been derived from mrouted. +#The mrouted program is covered by the license in the accompanying file +#named "LICENSE.mrouted". +# +#The mrouted program is COPYRIGHT 1989 by The Board of Trustees of +#Leland Stanford Junior University. # $FreeBSD$ PROG= pim6sd @@ -33,9 +83,9 @@ SRCS= mld6.c mld6_proto.c\ SRCS+= y.tab.h y.tab.h: cfparse.y CLEANFILES+= lex.yy.c y.tab.h y.tab.c -CFLAGS+= -g +CFLAGS+=-Wall CFLAGS+=-I. -I${.CURDIR} -CFLAGS+=-DINET6 -DPIM -DIOCTL_OK_ON_RAW_SOCKET -I${.OBJDIR} +CFLAGS+=-DINET6 -DPIM -DIOCTL_OK_ON_RAW_SOCKET -DHAVE_GETIFADDRS CFLAGS+=-DHAVE_STDARG_H DPADD= ${LIBY} ${LIBL} LDADD= -ly -ll diff --git a/usr.sbin/pim6sd/README.first b/usr.sbin/pim6sd/README.first index b58efbc80c96d..87a1c3cfef86d 100644 --- a/usr.sbin/pim6sd/README.first +++ b/usr.sbin/pim6sd/README.first @@ -1,4 +1,4 @@ - $FreeBSD$ +$FreeBSD$ WARNING WARNING WARNING: diff --git a/usr.sbin/pim6sd/callout.c b/usr.sbin/pim6sd/callout.c index 52eda4f6033d0..d2f9d04b64bb7 100644 --- a/usr.sbin/pim6sd/callout.c +++ b/usr.sbin/pim6sd/callout.c @@ -33,6 +33,7 @@ #include <stdlib.h> #include "debug.h" #include "defs.h" +#include "callout.h" /* the code below implements a callout queue */ diff --git a/usr.sbin/pim6sd/callout.h b/usr.sbin/pim6sd/callout.h index 61c4de344c0b0..6d08d3130a52e 100644 --- a/usr.sbin/pim6sd/callout.h +++ b/usr.sbin/pim6sd/callout.h @@ -32,13 +32,13 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". * */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * @@ -47,7 +47,7 @@ #ifndef CALLOUT_H -#define CALLOUT_H +#define CALLOUT_H #include "defs.h" diff --git a/usr.sbin/pim6sd/cfparse.h b/usr.sbin/pim6sd/cfparse.h index 256b3f1e31d84..b4f6758f0853f 100644 --- a/usr.sbin/pim6sd/cfparse.h +++ b/usr.sbin/pim6sd/cfparse.h @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 diff --git a/usr.sbin/pim6sd/cfparse.y b/usr.sbin/pim6sd/cfparse.y index 3bc4341a7a1a2..e0e358fd18b17 100644 --- a/usr.sbin/pim6sd/cfparse.y +++ b/usr.sbin/pim6sd/cfparse.y @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -50,7 +50,7 @@ #include "timer.h" #include "inet6.h" -#define set_param(var,val,p) \ +#define set_param(var,val,p) \ do {\ if ((var) != -1) {\ yywarn("%s doubly defined(ignore %d)", (p), (val));\ @@ -76,7 +76,8 @@ struct attr_list { }; enum {IFA_FLAG, IFA_PREFERENCE, IFA_METRIC, RPA_PRIORITY, RPA_TIME, - BSRA_PRIORITY, BSRA_TIME, IN6_PREFIX, THRESA_RATE, THRESA_INTERVAL}; + BSRA_PRIORITY, BSRA_TIME, BSRA_MASKLEN, IN6_PREFIX, THRESA_RATE, + THRESA_INTERVAL}; static int strict; /* flag if the grammer check is strict */ static struct attr_list *rp_attr, *bsr_attr, *grp_prefix, *regthres_attr, @@ -87,6 +88,8 @@ static int srcmetric, srcpref, helloperiod, jpperiod, granularity, static double helloperiod_coef, jpperiod_coef; static int debugonly; + +extern int yylex __P((void)); %} %union { @@ -102,7 +105,7 @@ static int debugonly; %token REVERSELOOKUP %token PHYINT IFNAME DISABLE PREFERENCE METRIC NOLISTENER %token GRPPFX -%token CANDRP CANDBSR TIME PRIORITY +%token CANDRP CANDBSR TIME PRIORITY MASKLEN %token NUMBER STRING SLASH %token REGTHRES DATATHRES RATE INTERVAL %token SRCMETRIC SRCPREF HELLOPERIOD GRANULARITY JPPERIOD @@ -295,6 +298,18 @@ bsr_attributes: == NULL) return(-1); } + | bsr_attributes MASKLEN NUMBER + { + int masklen = $3; + + if (masklen < 0 || masklen > 128) + yywarn("invalid mask length: %d (ignored)", + masklen); + else if (($$ = add_attribute_num($1, BSRA_MASKLEN, + masklen)) + == NULL) + return(-1); + } ; /* group_prefix <group-addr>/<prefix_len> */ @@ -315,6 +330,13 @@ grppfx_statement: prefix.plen); prefixok = 0; } + if (IN6_IS_ADDR_MC_NODELOCAL(&prefix.paddr) || + IN6_IS_ADDR_MC_LINKLOCAL(&prefix.paddr)) { + yywarn("group prefix (%s/%d) has a narrow scope " + "(ignored)", + inet6_fmt(&prefix.paddr), prefix.plen); + prefixok = 0; + } if (prefixok) { struct attr_list *new; @@ -328,7 +350,7 @@ grppfx_statement: new->type = IN6_PREFIX; new->attru.prefix = prefix; new->next = grp_prefix; - + grp_prefix = new; } } @@ -369,7 +391,7 @@ thres_attributes: return(-1); } -/* +/* * switch_data_threshold [rate <number> interval <number>] * Operation: reads and assigns the switch to the spt threshold due to * data packets, if used as DR. @@ -418,6 +440,10 @@ param_statement: { set_param(granularity, $2, "granularity"); } + | DATATIME NUMBER EOS + { + set_param(datatimo, $2, "data_timeout"); + } | REGSUPTIME NUMBER EOS { set_param(regsuptimo, $2, "register_suppression_timeout"); @@ -433,6 +459,19 @@ param_statement: ; %% +static struct attr_list *add_attribute_flag __P((struct attr_list *, int, + unsigned int)); +static struct attr_list *add_attribute_num __P((struct attr_list *, int, + double)); +static void free_attr_list __P((struct attr_list *)); +static int param_config __P((void)); +static int phyint_config __P((void)); +static int rp_config __P((void)); +static int bsr_config __P((void)); +static int grp_prefix_config __P((void)); +static int regthres_config __P((void)); +static int datathres_config __P((void)); + static struct attr_list * add_attribute_flag(list, type, flag) struct attr_list *list; @@ -440,7 +479,7 @@ add_attribute_flag(list, type, flag) unsigned int flag; { struct attr_list *p; - + if ((p = malloc(sizeof(*p))) == NULL) { yyerror("malloc failed"); return(NULL); @@ -461,7 +500,7 @@ add_attribute_num(list, type, num) double num; { struct attr_list *p; - + if ((p = malloc(sizeof(*p))) == NULL) { yyerror("malloc failed"); return(NULL); @@ -486,7 +525,7 @@ free_attr_list(list) } } -int +static int param_config() { struct uvif *v; @@ -533,17 +572,35 @@ param_config() log(LOG_DEBUG, 0, "pim_join_prune_holdtime set to: %u", pim_join_prune_holdtime); } - + IF_DEBUG(DEBUG_TIMER) { + log(LOG_DEBUG,0 , "timer interval set to: %u", timer_interval); + } + IF_DEBUG(DEBUG_PIM_TIMER) { + log(LOG_DEBUG,0 , "PIM data timeout set to: %u", + pim_data_timeout); + } + IF_DEBUG(DEBUG_PIM_REGISTER) { + log(LOG_DEBUG, 0, + "PIM register suppression timeout set to: %u", + pim_register_suppression_timeout); + log(LOG_DEBUG, 0, "PIM register probe time set to: %u", + pim_register_probe_time); + } + IF_DEBUG(DEBUG_PIM_ASSERT) { + log(LOG_DEBUG, 0, + "PIM assert timeout set to: %u", + pim_assert_timeout); + } return(0); } -int +static int phyint_config() { struct uvif *v; vifi_t vifi; struct attr_list *al; - + for (vifi = 0, v = uvifs; vifi < numvifs ; ++vifi , ++v) { for (al = (struct attr_list *)v->config_attr; al; al = al->next) { switch(al->type) { @@ -587,7 +644,7 @@ phyint_config() return(0); } -int +static int rp_config() { struct sockaddr_in6 *sa6_rp = NULL; @@ -686,15 +743,17 @@ rp_config() return(0); } -int +static int bsr_config() { struct sockaddr_in6 *sa6_bsr = NULL; struct attr_list *al; + int my_bsr_hash_masklen; /* initialization by default values */ my_bsr_period = PIM_DEFAULT_BOOTSTRAP_PERIOD; my_bsr_priority = PIM_DEFAULT_BSR_PRIORITY; + my_bsr_hash_masklen = RP_DEFAULT_IPV6_HASHMASKLEN; if (cand_bsr_ifname) { sa6_bsr = local_iface(cand_bsr_ifname); @@ -711,6 +770,10 @@ bsr_config() if (al->attru.number >= 0) my_bsr_priority = al->attru.number; break; + case BSRA_MASKLEN: + /* validation has been done. */ + my_bsr_hash_masklen = al->attru.number; + break; case BSRA_TIME: if (al->attru.number < 10) my_bsr_period = 10; @@ -729,22 +792,22 @@ bsr_config() if (!sa6_bsr) sa6_bsr = max_global_address(); /* this MUST suceed */ my_bsr_address = *sa6_bsr; + MASKLEN_TO_MASK6(my_bsr_hash_masklen, my_bsr_hash_mask); IF_DEBUG(DEBUG_PIM_BOOTSTRAP) { - log(LOG_DEBUG, 0, - "Local BSR address: %s", + log(LOG_DEBUG, 0, "Local BSR address: %s", inet6_fmt(&my_bsr_address.sin6_addr)); - log(LOG_DEBUG, 0, - "Local BSR priority : %u",my_bsr_priority); - log(LOG_DEBUG,0, - "Local BSR period is : %u sec.", + log(LOG_DEBUG, 0, "Local BSR priority : %u", my_bsr_priority); + log(LOG_DEBUG, 0, "Local BSR period is : %u sec.", my_bsr_period); + log(LOG_DEBUG, 0, "Local BSR hash mask length: %d", + my_bsr_hash_masklen); } return(0); } -int +static int grp_prefix_config() { struct attr_list *pl; @@ -786,7 +849,7 @@ grp_prefix_config() return(0); } -int +static int regthres_config() { struct attr_list *al; @@ -836,7 +899,7 @@ regthres_config() return(0); } -int +static int datathres_config() { struct attr_list *al; diff --git a/usr.sbin/pim6sd/cftoken.l b/usr.sbin/pim6sd/cftoken.l index 09725d3046a28..1a9abde99f7e1 100644 --- a/usr.sbin/pim6sd/cftoken.l +++ b/usr.sbin/pim6sd/cftoken.l @@ -2,7 +2,7 @@ /* * 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: @@ -14,7 +14,7 @@ * 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 @@ -52,7 +52,11 @@ int yy_first_time = 1; extern char configfilename[]; +#if 0 static void cfdebug_print __P((char *, char *, int)); +#endif + +extern int yylex __P((void)); %} /* common seciton */ @@ -536,6 +540,7 @@ slash \/ /* cand_bootstrap_router */ <S_CNF>cand_bootstrap_router { DP("begin cand_bsr"); BEGIN S_CANDBSR; return(CANDBSR); } <S_CANDBSR>priority { YYD_ECHO; return(PRIORITY); } +<S_CANDBSR>masklen { YYD_ECHO; return(MASKLEN); } <S_CANDBSR>time { YYD_ECHO; return(TIME); } <S_CANDBSR>{ifname} { YYD_ECHO; @@ -588,6 +593,7 @@ slash \/ } %% +#if 0 static void cfdebug_print(w, t, l) char *w, *t; @@ -595,6 +601,7 @@ cfdebug_print(w, t, l) { printf("<%d>%s [%s] (%d)\n", yy_start, w, t, l); } +#endif static void yyerror0(char *s, va_list ap) @@ -636,7 +643,7 @@ cfparse(strict, debugonly) int strict, debugonly; { if ((yyin = fopen(configfilename, "r")) == NULL) { - fprintf(stderr, "cfparse: fopen(%s)", configfilename); + fprintf(stderr, "cfparse: fopen(%s)\n", configfilename); return(-1); } diff --git a/usr.sbin/pim6sd/config.c b/usr.sbin/pim6sd/config.c index 04689ca1c07e1..7cbd7d86086a6 100644 --- a/usr.sbin/pim6sd/config.c +++ b/usr.sbin/pim6sd/config.c @@ -72,6 +72,9 @@ #include <net/if_var.h> #endif #include <netinet6/in6_var.h> +#ifdef HAVE_GETIFADDRS +#include <ifaddrs.h> +#endif #include <string.h> #include <errno.h> #include <ctype.h> @@ -80,47 +83,183 @@ #include <stdio.h> #include "debug.h" -void add_phaddr(struct uvif *v , struct sockaddr_in6 *addr,struct in6_addr *mask); -char *next_word(char **s); -int wordToOption(char *word); -int parse_phyint(char *s); -int parse_candidateRP(char *s); -int parse_group_prefix(char *s); -int parseBSR(char *s); -int parse_reg_threshold(char *s); -int parse_data_threshold(char *s); -int parse_default_source_metric(char *s); -int parse_default_source_preference(char *s); -int parse_hello_period(char *s); -int parse_granularity(char *s); -int parse_jp_period(char *s); -int parse_data_timeout(char *s); -int parse_register_suppression_timeout(char *s); -int parse_probe_time(char *s); -int parse_assert_timeout(char *s); +void add_phaddr(struct uvif *v, struct sockaddr_in6 *addr, + struct in6_addr *mask); void config_vifs_from_kernel() { - struct ifreq *ifrp,*ifend; register struct uvif *v; register vifi_t vifi; - int n,i; + int i; struct sockaddr_in6 addr; struct in6_addr mask; short flags; +#ifdef HAVE_GETIFADDRS + struct ifaddrs *ifap, *ifa; +#else + int n; int num_ifreq = 64; struct ifconf ifc; + struct ifreq *ifrp,*ifend; +#endif total_interfaces= 0; /* The total number of physical interfaces */ +#ifdef HAVE_GETIFADDRS + if (getifaddrs(&ifap)) + log(LOG_ERR, errno, "getifaddrs"); + + /* + * Loop through all of the interfaces. + */ + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + struct in6_ifreq ifr6; + + /* + * Ignore any interface for an address family other than IPv6. + */ + if (ifa->ifa_addr->sa_family != AF_INET6) { + /* Eventually may have IPv6 address later */ + total_interfaces++; + continue; + } + + memcpy(&addr, ifa->ifa_addr, sizeof(struct sockaddr_in6)); + + flags = ifa->ifa_flags; + + + /* + * Get netmask of the address. + */ + memcpy(&mask, + &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr, + sizeof(mask)); + + /* + * Get IPv6 specific flags, and ignore an anycast address. + * XXX: how about a deprecated, tentative, duplicated or + * detached address? + */ + memcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name)); + ifr6.ifr_addr = *(struct sockaddr_in6 *)ifa->ifa_addr; + if (ioctl(udp_socket, SIOCGIFAFLAG_IN6, &ifr6) < 0) { + log(LOG_ERR, errno, "ioctl SIOCGIFAFLAG_IN6 for %s", + inet6_fmt(&ifr6.ifr_addr.sin6_addr)); + } + else { + if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST) { + log(LOG_DEBUG, 0, "config_vifs_from_kernel: " + "%s on %s is an anycast address, ignored", + inet6_fmt(&ifr6.ifr_addr.sin6_addr), + ifa->ifa_name); + continue; + } + } + + if (IN6_IS_ADDR_LINKLOCAL(&addr.sin6_addr)) + { + addr.sin6_scope_id = if_nametoindex(ifa->ifa_name); +#ifdef __KAME__ + /* + * Hack for KAME kernel. + * Set sin6_scope_id field of a link local address and clear + * the index embedded in the address. + */ + /* clear interface index */ + addr.sin6_addr.s6_addr[2] = 0; + addr.sin6_addr.s6_addr[3] = 0; +#endif + } + + /* + * If the address is connected to the same subnet as one + * already installed in the uvifs array, just add the address + * to the list of addresses of the uvif. + */ + for(vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) + { + if(strcmp(v->uv_name, ifa->ifa_name) == 0 ) + { + add_phaddr(v, &addr, &mask); + break; + } + } + + if (vifi != numvifs) + continue; + + /* + * If there is room in the uvifs array, install this interface. + */ + if (numvifs == MAXMIFS) + { + log(LOG_WARNING, 0, + "too many vifs, ignoring %s", ifa->ifa_name); + continue; + } + + /* + * Everyone below is a potential vif interface. + * We don't care if it has wrong configuration or not + * configured at all. + */ + total_interfaces++; + + v = &uvifs[numvifs]; + v->uv_dst_addr = allpim6routers_group; + v->uv_subnetmask = mask; + strncpy(v->uv_name, ifa->ifa_name, IFNAMSIZ); + v->uv_ifindex = if_nametoindex(v->uv_name); + add_phaddr(v, &addr,&mask); + + /* prefix local calc. (and what about add_phaddr?...) */ + for (i = 0; i < sizeof(struct in6_addr); i++) + v->uv_prefix.sin6_addr.s6_addr[i] = + addr.sin6_addr.s6_addr[i] & mask.s6_addr[i]; + + if(flags & IFF_POINTOPOINT) + v->uv_flags |=(VIFF_REXMIT_PRUNES | VIFF_POINT_TO_POINT); + + /* + * Disable multicast routing on loopback interfaces and + * interfaces that do not support multicast. But they are + * still necessary, since global addresses maybe assigned only + * on such interfaces. + */ + if ((flags & IFF_LOOPBACK) != 0 || + (flags & IFF_MULTICAST) == 0) + v->uv_flags |= VIFF_DISABLED; + + IF_DEBUG(DEBUG_IF) + log(LOG_DEBUG,0, + "Installing %s (%s on subnet %s) ," + "as vif #%u - rate = %d", + v->uv_name,inet6_fmt(&addr.sin6_addr), + net6name(&v->uv_prefix.sin6_addr,&mask), + numvifs,v->uv_rate_limit); + + ++numvifs; + + + if( !(flags & IFF_UP)) + { + v->uv_flags |= VIFF_DOWN; + vifs_down = TRUE; + } + + } + + freeifaddrs(ifap); +#else /* !HAVE_GETIFADDRS */ ifc.ifc_len = num_ifreq * sizeof (struct ifreq); ifc.ifc_buf = calloc(ifc.ifc_len,sizeof(char)); while (ifc.ifc_buf) { caddr_t newbuf; if (ioctl(udp_socket,SIOCGIFCONF,(char *)&ifc) <0) - log(LOG_ERR, errno, "ioctl SIOCGIFCONF"); + log(LOG_ERR, errno, "ioctl SIOCGIFCONF"); /* * If the buffer was large enough to hold all the addresses * then break out, otherwise increase the buffer size and @@ -143,7 +282,7 @@ config_vifs_from_kernel() } if (ifc.ifc_buf == NULL) log(LOG_ERR, 0, "config_vifs_from_kernel: ran out of memory"); - + ifrp = (struct ifreq *) ifc.ifc_buf; ifend = (struct ifreq * ) (ifc.ifc_buf + ifc.ifc_len); @@ -162,7 +301,7 @@ config_vifs_from_kernel() n=sizeof(*ifrp); #else n=sizeof(*ifrp); -#endif +#endif /* * Ignore any interface for an address family other than IPv6. @@ -254,7 +393,7 @@ config_vifs_from_kernel() add_phaddr(v, &addr,&mask); break; } - } + } if( vifi != numvifs ) continue; @@ -265,9 +404,9 @@ config_vifs_from_kernel() if( numvifs == MAXMIFS ) { log(LOG_WARNING, 0, - "too many vifs, ignoring %s", ifr.ifr_name); + "too many vifs, ignoring %s", ifr.ifr_name); continue; - } + } /* * Everyone below is a potential vif interface. @@ -282,12 +421,12 @@ config_vifs_from_kernel() strncpy ( v->uv_name , ifr.ifr_name,IFNAMSIZ); v->uv_ifindex = if_nametoindex(v->uv_name); add_phaddr(v,&addr,&mask); - + /* prefix local calc. (and what about add_phaddr?...) */ for (i = 0; i < sizeof(struct in6_addr); i++) v->uv_prefix.sin6_addr.s6_addr[i] = addr.sin6_addr.s6_addr[i] & mask.s6_addr[i]; - + if(flags & IFF_POINTOPOINT) v->uv_flags |=(VIFF_REXMIT_PRUNES | VIFF_POINT_TO_POINT); @@ -310,14 +449,15 @@ config_vifs_from_kernel() ++numvifs; - - if( !(flags & IFF_UP)) + + if( !(flags & IFF_UP)) { v->uv_flags |= VIFF_DOWN; vifs_down = TRUE; } } +#endif /* HAVE_GETIFADDRS */ } void @@ -325,7 +465,7 @@ add_phaddr(struct uvif *v,struct sockaddr_in6 *addr,struct in6_addr *mask) { struct phaddr *pa; int i; - + if( (pa=malloc(sizeof(*pa))) == NULL) log(LOG_ERR, 0, "add_phaddr: memory exhausted"); @@ -353,1257 +493,3 @@ add_phaddr(struct uvif *v,struct sockaddr_in6 *addr,struct in6_addr *mask) pa->pa_next = v->uv_addrs; v->uv_addrs = pa; } - -void -config_vifs_from_file() -{ - FILE *f; - char linebuf[100]; - char *w,*s; - struct ifconf ifc; - int option; - char ifbuf[BUFSIZ]; - u_int8 *data_ptr; - - if((f=fopen(configfilename,"r"))==NULL) - { - if( errno != ENOENT) - log(LOG_ERR,errno,"Can't open %s",configfilename); - log(LOG_WARNING,errno,"Can't open %s",configfilename); - return; - } - /* - * Note that sizeof(pim6_enocd_uni_addr_t) might be larger than - * the length of the Encoded-Unicast-address field(18 byte) due to - * some padding put in the compiler. However, it doesn't matter - * since we use the space just as a buffer(i.e not as the message). - */ - cand_rp_adv_message.buffer = (u_int8 *)malloc( 4 + sizeof(pim6_encod_uni_addr_t) + - 255*sizeof(pim6_encod_grp_addr_t)); - if(cand_rp_adv_message.buffer == NULL) - log(LOG_ERR,errno,"Candrpadv Buffer allocation"); - - cand_rp_adv_message.prefix_cnt_ptr = cand_rp_adv_message.buffer; - - /* By default, if no group_prefix configured, then prefix_cnt == 0 - * implies group_prefix = ff::/8 and masklen = 8. - */ - - *cand_rp_adv_message.prefix_cnt_ptr = 0; - cand_rp_adv_message.insert_data_ptr = cand_rp_adv_message.buffer; - - /* TODO: XXX: HARDCODING!!! */ - cand_rp_adv_message.insert_data_ptr += (4 + 18); - - ifc.ifc_buf = ifbuf; - ifc.ifc_len = sizeof(ifbuf); - if(ioctl(udp_socket,SIOCGIFCONF,(char *)&ifc) < 0) - log(LOG_ERR, errno, "ioctl SIOCGIFCONF"); - - while( fgets(linebuf, sizeof(linebuf),f) != NULL ) - { - s = linebuf; - w = next_word(&s); - option = wordToOption(w); - switch(option) - { - case EMPTY: - continue; - break; - case PHYINT: - parse_phyint(s); - break; - case CANDIDATE_RP: - parse_candidateRP(s); - break; - case GROUP_PREFIX: - parse_group_prefix(s); - break; - case BOOTSTRAP_RP: - parseBSR(s); - break; - case REG_THRESHOLD: - parse_reg_threshold(s); - break; - case DATA_THRESHOLD: - parse_data_threshold(s); - break; - case DEFAULT_SOURCE_METRIC: - parse_default_source_metric(s); - break; - case DEFAULT_SOURCE_PREFERENCE : - parse_default_source_preference(s); - break; - case HELLO_PERIOD : - parse_hello_period(s); - break; - case GRANULARITY : - parse_granularity(s); - break; - case JOIN_PRUNE_PERIOD : - parse_jp_period(s); - break; - case DATA_TIMEOUT : - parse_data_timeout(s); - break; - case REGISTER_SUPPRESSION_TIMEOUT : - parse_register_suppression_timeout(s); - break; - case PROBE_TIME : - parse_probe_time(s); - break; - case ASSERT_TIMEOUT: - parse_assert_timeout(s); - break; - default: - log(LOG_WARNING, 0, "unknown command '%s' in %s", - w, configfilename); - - } - } - cand_rp_adv_message.message_size = cand_rp_adv_message.insert_data_ptr - cand_rp_adv_message.buffer; - if (cand_rp_flag != FALSE) - { - my_cand_rp_holdtime = 2.5 * my_cand_rp_adv_period; - - /* TODO: HARDCODING! */ - data_ptr = cand_rp_adv_message.buffer + 1; /* WARNING */ - PUT_BYTE(my_cand_rp_priority,data_ptr); - PUT_HOSTSHORT(my_cand_rp_holdtime, data_ptr); - PUT_EUADDR6(my_cand_rp_address.sin6_addr,data_ptr); - IF_DEBUG(DEBUG_PIM_CAND_RP) - { - log(LOG_DEBUG, 0, - "Local Cand-RP address is : %s", - inet6_fmt(&my_cand_rp_address.sin6_addr)); - log(LOG_DEBUG, 0, - "Local Cand-RP priority is : %u",my_cand_rp_priority); - log(LOG_DEBUG, 0, - "Local Cand-RP advertisement period is : %u sec.", - my_cand_rp_adv_period); - } - } - - - if( cand_bsr_flag!=FALSE) - { - IF_DEBUG(DEBUG_PIM_BOOTSTRAP) - { - log(LOG_DEBUG, 0, - "Local BSR address: %s", - inet6_fmt(&my_bsr_address.sin6_addr)); - log(LOG_DEBUG, 0, - "Local BSR priority : %u",my_bsr_priority); - log(LOG_DEBUG,0, - "Local BSR period is : %u sec.", - my_bsr_period); - - } - - } - - IF_DEBUG(DEBUG_SWITCH) - { - log(LOG_DEBUG,0,"reg_rate_limit set to %u (bits/s)" , pim_reg_rate_bytes); - log(LOG_DEBUG,0,"reg_rate_interval set to %u s.",pim_reg_rate_check_interval); - log(LOG_DEBUG,0,"data_rate_limit set to %u (bits/s)" , pim_data_rate_bytes); - log(LOG_DEBUG,0,"data_rate_interval set to %u s.",pim_data_rate_check_interval); - } - - IF_DEBUG(DEBUG_PIM_HELLO) - { - log(LOG_DEBUG,0, "pim_hello_period set to: %u", pim_hello_period); - log(LOG_DEBUG,0, "pim_hello_holdtime set to: %u", pim_hello_holdtime); - } - - IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) - { - log(LOG_DEBUG,0, "pim_join_prune_period set to: %u", pim_join_prune_period); - log(LOG_DEBUG,0, "pim_join_prune_holdtime set to: %u", pim_join_prune_holdtime); - } - - fclose(f); - -} -/* - * function name: wordToOption - * input: char *word, a pointer to the word - * output: int; a number corresponding to the code of the word - * operation: converts the result of the string comparisons into numerics. - * comments: called by config_vifs_from_file() - */ - -int wordToOption(char *word) -{ - if (EQUAL(word, "")) - return EMPTY; - if (EQUAL(word, "phyint")) - return PHYINT; - if (EQUAL(word, "cand_rp")) - return CANDIDATE_RP; - if (EQUAL(word, "group_prefix")) - return GROUP_PREFIX; - if (EQUAL(word, "cand_bootstrap_router")) - return BOOTSTRAP_RP; - if (EQUAL(word, "switch_register_threshold")) - return REG_THRESHOLD; - if (EQUAL(word, "switch_data_threshold")) - return DATA_THRESHOLD; - if (EQUAL(word, "default_source_metric")) - return DEFAULT_SOURCE_METRIC; - if (EQUAL(word, "default_source_preference")) - return DEFAULT_SOURCE_PREFERENCE; - if (EQUAL(word, "hello_period")) - return HELLO_PERIOD; - if (EQUAL(word, "granularity")) - return GRANULARITY; - if (EQUAL(word, "join_prune_period")) - return JOIN_PRUNE_PERIOD; - if (EQUAL(word, "data_timeout")) - return DATA_TIMEOUT; - if (EQUAL(word, "register_suppression_timeout")) - return REGISTER_SUPPRESSION_TIMEOUT; - if (EQUAL(word, "probe_time")) - return PROBE_TIME; - if (EQUAL(word, "assert_timeout")) - return PROBE_TIME; - return UNKNOWN; -} - -/* - * function name: parse_phyint - * input: char *s, pointing to the parsing point of the file - * output: int (TRUE if the parsing was successful, o.w. FALSE) - * operation: parses the physical interface file configurations, if any. - * The general form is: - * phyint <ifname> [disable] [preference <p>] [metric <m>] - */ - - -int parse_phyint(char *s) -{ - char *w,c,*ifname; - vifi_t vifi; - struct uvif *v; - u_int n; - - if(EQUAL((w = next_word(&s)),"")) - { - log(LOG_WARNING, 0, "Missing phyint name in %s", configfilename); - return FALSE; - } - ifname = w; - - for (vifi = 0,v=uvifs;vifi <= numvifs ; ++vifi , ++v) - { - if(vifi == numvifs) - { - log(LOG_WARNING, 0, - "Invalid phyint name (maybe not configured..) '%s' " - "in %s", w, configfilename); - return FALSE; - } - - if(strcmp(v->uv_name,ifname)) - continue; - - while(!EQUAL((w = next_word(&s)),"")) - { - if(EQUAL(w,"disable")) - v->uv_flags |=VIFF_DISABLED; - else if (EQUAL(w, "nolistener")) - v->uv_flags |= VIFF_NOLISTENER; - else - { - if(EQUAL(w,"preference")) - { - if(EQUAL((w=next_word(&s)),"")) - { - log(LOG_WARNING, 0, - "Missing preference for " - "phyint %s in %s", - ifname, configfilename); - } - else - { - if (sscanf(w,"%u%c",&n,&c) != 1 || - n < 1 || n > 255 ) - { - log(LOG_WARNING, 0, - "Invalid preference " - "'%s' for phyint %s " - "in %s", - w, ifname, - configfilename); - } - else - { - IF_DEBUG(DEBUG_ASSERT) - log(LOG_DEBUG, 0,"Config setting default local preference on %d to %s",n,ifname); - v->uv_local_pref = n; - } - } - } - else - { - if(EQUAL(w, "metric")) - { - if(EQUAL((w = next_word(&s)), "")) - { - log(LOG_WARNING,0, - "Missing metric for " - "phyint %s in %s", - ifname, - configfilename); - } - else - { - if (sscanf(w, "%u%c", &n, &c) != 1 || - n < 1 || n > 1024 ) - { - log(LOG_WARNING,0, - "Invalid metric '%s' for phyint %s in %s", - w, ifname,configfilename); - } - else - { - IF_DEBUG(DEBUG_ASSERT) - log(LOG_DEBUG,0, - "Config setting default local metric on %d to %s.", - n,ifname); - v->uv_local_metric = n; - } - - } - } - } - } - } - break; - } - return(TRUE); -} - -/* - * function name: parse_candidateRP - * input: char *s - * output: int (TRUE if the parsing was successful, o.w. FALSE) - * operation: parses the candidate RP information. - * The general form is: - * 'cand_rp <ifname> [priority <number>] [time <number>]'. - */ -int -parse_candidateRP(char *s) -{ - char *w; - struct sockaddr_in6 *sa6_rp; - u_int time = PIM_DEFAULT_CAND_RP_ADV_PERIOD; - u_int priority = PIM_DEFAULT_CAND_RP_PRIORITY; - - sa6_rp = NULL; - cand_rp_flag = FALSE; - - my_cand_rp_adv_period = PIM_DEFAULT_CAND_RP_ADV_PERIOD; - - while(!EQUAL((w = next_word(&s)),"")) - { - if((!EQUAL(w,"priority")) && (!EQUAL(w,"time"))) - { - /* - * if the interface is specified and is valid - * we take the max global address of the interface - * (aliasing) else look at the end of the function. - */ - sa6_rp = local_iface(w); - if(!sa6_rp) - log(LOG_WARNING, 0, - "cand_rp '%s' in %s is not configured." - "take the max local address the router..", - w, configfilename); - } - else - { - if (EQUAL(w,"priority")) - { - if (EQUAL((w = next_word(&s)),"")) - { - log(LOG_WARNING,0, - "Missing priority ; set to default " - ": %d (0 is highest )",priority); - } - else - { - if (sscanf(w,"%u",&priority)!= 1 ) - { - priority = PIM_DEFAULT_CAND_RP_PRIORITY; - log(LOG_WARNING, 0, - "Invalid priority '%' " - "for cand_rp;set to default " - "(0 is highest) : %d", - w, priority); - } - } - } - else - { - if (EQUAL((w = next_word(&s)),"")) - { - log(LOG_WARNING, 0, - "Missing cand_adv period ;" - "set to default : %d",time); - } - else - { - if (sscanf(w,"%u",&time)!= 1 ) - { - time = PIM_DEFAULT_CAND_RP_ADV_PERIOD; - log(LOG_WARNING, 0, - "Invalid cand_adv_period " - "'%s';set to default : %d", - w,time); - - } - else - { - if( time > (my_cand_rp_adv_period = ~0)) - time = my_cand_rp_adv_period; - else - if(time <10) - time = 10; - else - if (time > PIM_DEFAULT_CAND_RP_ADV_PERIOD) - time = PIM_DEFAULT_CAND_RP_ADV_PERIOD; - my_cand_rp_adv_period = time; - } - } - } - } - } - - if(!sa6_rp) - sa6_rp= max_global_address(); - - my_cand_rp_address=*sa6_rp; - my_cand_rp_priority = priority; - my_cand_rp_adv_period = time; - cand_rp_flag = TRUE; - - return TRUE; -} - -/* - * function name: parse_group_prefix - * input: char *s - * output: int - * operation: parse group_prefix configured information. - * General form: 'group_prefix <group-addr>/<prefix_len>'. - */ -int -parse_group_prefix(char *s) -{ - char *w; - struct in6_addr group_addr; - u_int32 masklen=PIM_GROUP_PREFIX_DEFAULT_MASKLEN; - - w=next_word(&s); - if (EQUAL(w,"")) - { - log(LOG_WARNING, 0, - "Configuration error for 'group_prefix' in %s: no group_addr. " - "Ignoring...", configfilename); - return FALSE; - } - - w=strtok(w,"/"); - - if ( inet_pton(AF_INET6,w,(void *)&group_addr) != 1 ) - { - log(LOG_WARNING, 0, - "Config error in %s : Bad ddress formatt.Ignoring..", - configfilename); - return FALSE; - } - if (!IN6_IS_ADDR_MULTICAST(&group_addr)) - { - log(LOG_WARNING,0, - "Config error in %s: '%s' is not a mcast addr.Ignoring", - configfilename, - inet6_fmt(&group_addr)); - return FALSE; - } - if (!(~(*cand_rp_adv_message.prefix_cnt_ptr))) - { - log(LOG_WARNING, 0, - "Too many group_prefix configured. Truncating..."); - return FALSE; - } - - w=strtok(NULL,"/"); - if(w==NULL) - { - log(LOG_WARNING,0, - "Config error in %s : missing group prefix.Ignoring..", - configfilename); - return FALSE; - } - if ( sscanf(w,"%u",&masklen) ==1 ) - { - if (masklen > (sizeof(group_addr) * 8)) - masklen = (sizeof(group_addr)*8); - else - if (masklen <PIM_GROUP_PREFIX_DEFAULT_MASKLEN) - masklen = PIM_GROUP_PREFIX_DEFAULT_MASKLEN; - } - - - PUT_EGADDR6(group_addr, (u_int8)masklen, 0, - cand_rp_adv_message.insert_data_ptr); - (*cand_rp_adv_message.prefix_cnt_ptr)++; - - return TRUE; - -} -/* - * function name: parseBSR - * input: char *s - * output: int - * operation: parse the candidate BSR configured information. - * General form: - * 'cand_bootstrap_router <ifname> [priority <number>]'. - * this function is similar to parse_candrp - */ - -int -parseBSR(char *s) -{ - char *w; - struct sockaddr_in6 *sa6_bsr; - u_int32 priority = PIM_DEFAULT_BSR_PRIORITY; - u_int time = PIM_DEFAULT_BOOTSTRAP_PERIOD; - my_bsr_period = PIM_DEFAULT_BOOTSTRAP_PERIOD; - - sa6_bsr = NULL; - cand_bsr_flag = FALSE; - - while(!EQUAL((w = next_word(&s)),"")) - { - if((!EQUAL(w,"priority")) && (!EQUAL(w,"time"))) - { - - sa6_bsr = local_iface(w); - if(!sa6_bsr) - { - log(LOG_WARNING,0, - "cand_bootstrap_router '%s' in %s is not " - "configured.Take the max router address.", - w,configfilename); - } - } - else - { - if(EQUAL(w,"priority")) - { - if (EQUAL((w = next_word(&s)),"")) - { - log(LOG_WARNING, 0, - "Missing priority for the bsr;set to " - "default (0 is lowest): %d",priority); - } - else - { - if (sscanf(w,"%u",&priority)!= 1 ) - { - priority = PIM_DEFAULT_BSR_PRIORITY; - log(LOG_WARNING, 0, - "Invalid priority '%s'for " - "the bsr;set to default : %d", - w, priority); - } - else - { - if( priority > (my_bsr_priority = ~0)) - priority = my_bsr_priority; - my_bsr_priority = (u_int8)priority; - } - } - } - else - { - if( EQUAL((w=next_word(&s)),"")) - { - log(LOG_WARNING,0, - "Missing bsr period ;" - "set to default : %d ",time); - } - else - { - if(sscanf(w,"%u",&time)!=1) - { - time=PIM_DEFAULT_BOOTSTRAP_PERIOD; - log(LOG_WARNING,0, - "Invalid bsr period" - "'%s';set to default : %d", - w,time); - } - else - my_bsr_period=time; - } - } - } - } - - if(!sa6_bsr) - sa6_bsr = max_global_address(); - - my_bsr_address=*sa6_bsr; - my_bsr_priority = priority; - MASKLEN_TO_MASK6(RP_DEFAULT_IPV6_HASHMASKLEN,my_bsr_hash_mask); - cand_bsr_flag = TRUE; - - return TRUE; -} - -/* - * function name: parse_reg_threshold - * input: char *s - * output: int (TRUE if successful, FALSE o.w.) - * operation: reads and assigns the switch to the spt threshold - * due to registers for the router, if used as RP. - * Maybe extended to support different thresholds - * for different groups(prefixes). - * General form: - * 'switch_register_threshold [rate <number> interval <number>]'. - * comments: called by config_vifs_from_file() - */ - - -int parse_reg_threshold(char *s) -{ - char *w; - u_int rate=PIM_DEFAULT_REG_RATE; - u_int interval= PIM_DEFAULT_REG_RATE_INTERVAL; - - while(!EQUAL((w=next_word(&s)),"")) - { - if(EQUAL(w,"rate")) - { - if(EQUAL((w=next_word(&s)),"")) - { - log(LOG_WARNING,0, - "switch_register_threshold : missing rate ; " - "set to default : %u (bits/s)", - rate); - } - else - { - if(sscanf(w,"%u",&rate)!=1) - { - rate = PIM_DEFAULT_REG_RATE; - log(LOG_WARNING, 0, - "switch_register_threshold : " - "Invalid rate '%s' , set to defaut :" - " %u (bits/s)", - w,rate); - } - } - } - else - { - if(EQUAL(w,"interval")) - { - if(EQUAL((w = next_word(&s)),"")) - { - log(LOG_WARNING,0,"switch_register_threshold : missing interval ; set to default : %u s.", - interval); - } - else - { - if(sscanf(w,"%u",&interval) != 1) - { - interval = PIM_DEFAULT_REG_RATE_INTERVAL; - log(LOG_WARNING,0,"switch_register_threshold : Invalid interval '%s' ; set to default : %u s.", - w,interval); - } - } - } - else - { - log(LOG_WARNING,0,"swhitch_register_threshold : Invalid parameter %s",w); - } - } - } - - if( interval < timer_interval) - { - interval = timer_interval; - log(LOG_WARNING,0,"switch_register_threshold : Interval too short , set to default : %u s.", - interval); - } - - pim_reg_rate_bytes = (rate * interval ) /10; - pim_reg_rate_check_interval = interval; - - return TRUE; - -} -/* - * function name: parse_data_threshold - * input: char *s - * output: int - * operation: reads and assigns the switch to the spt threshold - * due to data packets, if used as DR. - * General form: - * 'switch_data_threshold [rate <number> interval <number>]'. - * similar to register_threshold... - */ - -int parse_data_threshold(char *s) -{ - char *w; - u_int rate=PIM_DEFAULT_DATA_RATE; - u_int interval= PIM_DEFAULT_DATA_RATE_INTERVAL; - - while(!EQUAL((w=next_word(&s)),"")) - { - if(EQUAL(w,"rate")) - { - if(EQUAL((w=next_word(&s)),"")) - { - log(LOG_WARNING,0,"switch_data_threshold : missing rate value ; set to defaut : %u (bits/s)", - rate); - } - else - { - if(sscanf(w,"%u",&rate)!=1) - { - rate = PIM_DEFAULT_DATA_RATE; - log(LOG_WARNING,0,"switch_data_threshold : Invalid rate '%s' ; set to default : %u (bits/s)", - w,rate); - } - } - } - else - { - if(EQUAL(w,"interval")) - { - if(EQUAL((w = next_word(&s)),"")) - { - log(LOG_WARNING,0,"switch_data_threshold : missing interval value ; set to default : %u s.", - interval); - } - else - { - if(sscanf(w,"%u",&interval) != 1) - { - interval = PIM_DEFAULT_DATA_RATE_INTERVAL; - log(LOG_WARNING,0,"switch_data_threshold : Invalid interval '%s' ; set to default : %u s.", - w,interval); - } - } - } - else - { - log(LOG_WARNING,0,"swhitch_data_threshold :Invalid Parameter %s",w); - } - } - } - - if( interval < timer_interval) - { - interval = timer_interval; - log(LOG_WARNING,0,"switch_data_threshold : interval too short set to default : %u s.", - interval); - } - - pim_data_rate_bytes = (rate * interval ) /10; - pim_data_rate_check_interval = interval; - - return TRUE; - -} - -/* - * function name: parse_default_source_metric - * input: char *s - * output: int - * operation: reads and assigns the default source metric, if no reliable - * unicast routing information available. - * General form: - * 'default_source_metric <number>'. - * default pref and metric statements should precede all phyint - * statements in the config file. - */ - - -int parse_default_source_metric(char *s) -{ - char *w; - u_int value; - vifi_t vifi; - struct uvif *v; - - value = DEFAULT_LOCAL_METRIC; - - if (EQUAL((w = next_word(&s)), "")) - { - log(LOG_WARNING,0, - "Missing source metric value ; set to default %u", - value); - } - else - { - if (sscanf(w, "%u", &value) != 1) - { - value = DEFAULT_LOCAL_METRIC; - log(LOG_WARNING,0, - "Invalid source metric value '%s' ;set to default %u", - w,value); - } - default_source_metric = value; - log(LOG_INFO,0, "Default_source_metric is : %u", default_source_metric); - - for (vifi = 0, v = uvifs; vifi < MAXVIFS; ++vifi, ++v) - { - v->uv_local_metric = default_source_metric; - } - - - } - return(TRUE); -} - -/* - * function name: parse_default_source_preference - * input: char *s - * output: int - * operation: reads and assigns the default source preference, if no reliable - * unicast routing information available. - * General form: - * 'default_source_preference <number>'. - * default pref and metric statements should precede all phyint - * statements in the config file. - */ - -int parse_default_source_preference(char *s) -{ - char *w; - u_int value; - vifi_t vifi; - struct uvif *v; - - value = DEFAULT_LOCAL_PREF; - - if (EQUAL((w = next_word(&s)), "")) - { - log(LOG_WARNING,0, - "Missing source preference ; set to default %u", - value); - } - else - { - if (sscanf(w, "%u", &value) != 1) - { - value = DEFAULT_LOCAL_PREF; - log(LOG_WARNING,0, - "Invalid source preference value '%s' ;set to default %u", - w,value); - } - default_source_preference = value; - log(LOG_INFO,0, "default_source_preference set to: %u", default_source_preference); - - for (vifi = 0, v = uvifs; vifi < MAXVIFS; ++vifi, ++v) - { - v->uv_local_pref = default_source_preference; - } - - - } - return(TRUE); -} - -/* - * function name: parse_hello_period - * input: char *s - * output: int - * operation: reads and assigns the hello period for a pim router - * General form: - * 'hello_period <number> <coef>'. - * number is the period in second between 2 hello messages - * and coef is the coef to deterimine the hello holdtime - * default : 3.5 - */ - -int parse_hello_period(char *s) -{ - char *w; - u_int hellop; - float coef; - - hellop = PIM_TIMER_HELLO_PERIOD; - coef = 3.5; - - if (EQUAL((w = next_word(&s)), "")) - { - log(LOG_WARNING,0, - "Missing hello period ; set to default %u", - hellop); - } - else - { - if (sscanf(w, "%u", &hellop) != 1) - { - hellop = PIM_TIMER_HELLO_PERIOD; - log(LOG_WARNING,0, - "Invalid hello period value '%s' ;set to default %u", - w,hellop); - } - pim_hello_period = hellop; - - if (!EQUAL((w=next_word(&s)),"")) - { - if (sscanf(w, "%f", &coef) != 1) - { - coef = 3.5; - log(LOG_WARNING,0, - "Invalid hello period coef '%s' ;set to default %.1f", - w,coef); - } - if(coef<=1) - { - coef = 3.5; - log(LOG_WARNING,0, - "for hello period coef must be > 1;set to default %.1f", - coef); - } - - } - - - } - pim_hello_holdtime = coef*pim_hello_period; - return(TRUE); -} -/* - * function name: parse_jp_period - * input: char *s - * output: int - * operation: reads and assigns the join/prune period for a pim router - * General form: - * 'join_prune_period <number> <coef>'. - * number is the period in second between 2 join/prune messages - * and coef is the coef to deterimine the join/prune holdtime - * default : 3.5 - * This function is similar to the function above - */ - -int parse_jp_period(char *s) -{ - char *w; - u_int jpp; - float coef; - - jpp = PIM_JOIN_PRUNE_PERIOD; - coef = 3.5; - - if (EQUAL((w = next_word(&s)), "")) - { - log(LOG_WARNING,0, - "Missing join/prune period ; set to default %u", - jpp); - } - else - { - if (sscanf(w, "%u", &jpp) != 1) - { - jpp = PIM_JOIN_PRUNE_PERIOD; - log(LOG_WARNING,0, - "Invalid join/prune period value '%s' ;set to default %u", - w,jpp); - } - - pim_join_prune_period = jpp; - - if (!EQUAL((w=next_word(&s)),"")) - { - if (sscanf(w, "%f", &coef) != 1) - { - coef = 3.5; - log(LOG_WARNING,0, - "Invalid join/prune period coef '%s' ;set to default %.1f", - w,coef); - } - if(coef<=1) - { - coef = 3.5; - log(LOG_WARNING,0, - "for join/prune period coef must be > 1;set to default %.1f", - coef); - } - - } - - - } - pim_join_prune_holdtime = coef*pim_join_prune_period; - return(TRUE); -} - - -/* function name : parse_granularity - * input char *s - * output int - * operation : reads and assigns the granularity of the demon's timer - * General form : - * 'granularity <number> - * number is the period in seconds between each "tics" of the virtual time. - * default : 5 s. - */ -int parse_granularity(char *s) -{ - char *w; - u_int granu; - - granu = DEFAULT_TIMER_INTERVAL; - - if( EQUAL((w= next_word(&s)),"")) - { - log(LOG_WARNING,0, - "Missing timer granularity ; set to default %u", - granu); - return FALSE; - } - else - { - if( sscanf(w,"%u",&granu)!=1) - { - granu=DEFAULT_TIMER_INTERVAL; - log(LOG_WARNING,0, - "Invalid timer granularity value '%s' ; set to default %u", - w,granu); - } - timer_interval = granu; - if(granu < 1) - { - granu = DEFAULT_TIMER_INTERVAL; - log(LOG_WARNING,0, - "Timer granularity MUST be > 1! ; set to default %u", - granu); - } - } - - timer_interval = granu; - return TRUE; -} - -/* function name : parse_data_timeout - * input char *s - * output int - * operation : reads and assigns the data_timeout of each (S,G) - * General form : - * 'data_timeout <number> - * default : 210 s. - */ -int parse_data_timeout(char *s) -{ - char *w; - u_int time; - - time = PIM_DATA_TIMEOUT; - - if( EQUAL((w= next_word(&s)),"")) - { - log(LOG_WARNING,0, - "Missing data timeout ; set to default %u", - time); - return FALSE; - } - else - { - if( sscanf(w,"%u",&time)!=1) - { - time=PIM_DATA_TIMEOUT; - log(LOG_WARNING,0, - "Invalid data timeout value '%s' ; set to default %u", - w,time); - } - pim_data_timeout = time; - if(time < 1) - { - time = PIM_DATA_TIMEOUT; - log(LOG_WARNING,0, - "Data timeout must be > 1! ; set to default %u", - time); - } - } - - pim_data_timeout = time; - return TRUE; -} - -/* function name : parse_register_suppression_timeout - * input char *s - * output int - * operation : reads and assigns the register_suppression_timeout - * General form : - * 'register_suppression_timeout <number> - * default : 60 s. - */ -int parse_register_suppression_timeout(char *s) -{ - char *w; - u_int time; - - time = PIM_REGISTER_SUPPRESSION_TIMEOUT; - - if( EQUAL((w= next_word(&s)),"")) - { - log(LOG_WARNING,0, - "Missing register suppression timeout ; set to default %u", - time); - return FALSE; - } - else - { - if( sscanf(w,"%u",&time)!=1) - { - time=PIM_REGISTER_SUPPRESSION_TIMEOUT; - log(LOG_WARNING,0, - "Invalid register suppression timeout value '%s' ; set to default %u", - w,time); - } - pim_register_suppression_timeout = time; - if(time < 1) - { - time = PIM_REGISTER_SUPPRESSION_TIMEOUT; - log(LOG_WARNING,0, - "Register suppression timeout must be > 1! ; set to default %u", - time); - } - } - - pim_register_suppression_timeout = time; - return TRUE; -} - -/* function name : parse_probe_time - * input char *s - * output int - * operation : reads and assigns the probe_time for null-register - * General form : - * 'probe_time <number> - * default : 5 s. - */ -int parse_probe_time(char *s) -{ - char *w; - u_int time; - - time = PIM_REGISTER_PROBE_TIME; - - if( EQUAL((w= next_word(&s)),"")) - { - log(LOG_WARNING,0, - "Missing register probe time ; set to default %u", - time); - return FALSE; - } - else - { - if( sscanf(w,"%u",&time)!=1) - { - time=PIM_REGISTER_PROBE_TIME; - log(LOG_WARNING,0, - "Invalid register probe time value '%s' ; set to default %u", - w,time); - } - pim_register_probe_time = time; - if(time < 1) - { - time = PIM_REGISTER_SUPPRESSION_TIMEOUT; - log(LOG_WARNING,0, - "Register probe time must be > 1! ; set to default %u", - time); - } - } - - pim_register_probe_time = time; - return TRUE; -} - -/* function name : parse_assert_timeout - * input char *s - * output int - * operation : reads and assigns the assert timeout - * General form : - * 'assert_timeout <number> - * default : 180 s. - */ -int parse_assert_timeout(char *s) -{ - char *w; - u_int time; - - time = PIM_ASSERT_TIMEOUT; - - if( EQUAL((w= next_word(&s)),"")) - { - log(LOG_WARNING,0, - "Missing assert time out; set to default %u", - time); - return FALSE; - } - else - { - if( sscanf(w,"%u",&time)!=1) - { - time=PIM_ASSERT_TIMEOUT; - log(LOG_WARNING,0, - "Invalid assert time out value '%s' ; set to default %u", - w,time); - } - pim_assert_timeout = time; - if(time < 1) - { - time = PIM_ASSERT_TIMEOUT; - log(LOG_WARNING,0, - "Assert time out must be > 1! ; set to default %u", - time); - } - } - - pim_assert_timeout = time; - return TRUE; -} - - - - -char *next_word(char **s) -{ - char *w; - - w = *s; - while (*w == ' ' || *w == '\t') - w++; - - *s = w; - for(;;) { - switch (**s) { - case ' ' : - case '\t' : - **s = '\0'; - (*s)++; - return(w); - case '\n' : - case '#' : - **s = '\0'; - return(w); - case '\0' : - return(w); - default : - if (isascii(**s) && isupper(**s)) - **s = tolower(**s); - (*s)++; - } - } -} diff --git a/usr.sbin/pim6sd/config.h b/usr.sbin/pim6sd/config.h index deffe3f3825bb..5ce659312e931 100644 --- a/usr.sbin/pim6sd/config.h +++ b/usr.sbin/pim6sd/config.h @@ -32,12 +32,12 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * @@ -45,29 +45,29 @@ */ #ifndef CONFIG_H -#define CONFIG_H +#define CONFIG_H -#define UNKNOWN -1 -#define EMPTY 1 -#define PHYINT 2 -#define CANDIDATE_RP 3 -#define GROUP_PREFIX 4 -#define BOOTSTRAP_RP 5 -#define REG_THRESHOLD 6 -#define DATA_THRESHOLD 7 -#define DEFAULT_SOURCE_METRIC 8 -#define DEFAULT_SOURCE_PREFERENCE 9 -#define HELLO_PERIOD 10 -#define GRANULARITY 11 -#define JOIN_PRUNE_PERIOD 12 -#define DATA_TIMEOUT 13 -#define REGISTER_SUPPRESSION_TIMEOUT 14 -#define PROBE_TIME 15 -#define ASSERT_TIMEOUT 16 +#define UNKNOWN -1 +#define EMPTY 1 +#define PHYINT 2 +#define CANDIDATE_RP 3 +#define GROUP_PREFIX 4 +#define BOOTSTRAP_RP 5 +#define REG_THRESHOLD 6 +#define DATA_THRESHOLD 7 +#define DEFAULT_SOURCE_METRIC 8 +#define DEFAULT_SOURCE_PREFERENCE 9 +#define HELLO_PERIOD 10 +#define GRANULARITY 11 +#define JOIN_PRUNE_PERIOD 12 +#define DATA_TIMEOUT 13 +#define REGISTER_SUPPRESSION_TIMEOUT 14 +#define PROBE_TIME 15 +#define ASSERT_TIMEOUT 16 -#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0) +#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0) -void config_vifs_from_kernel(); -void config_vifs_from_file(); +void config_vifs_from_kernel __P((void)); +void config_vifs_from_file __P((void)); #endif diff --git a/usr.sbin/pim6sd/crc.c b/usr.sbin/pim6sd/crc.c index 917371eee5f78..ca16b63478b48 100644 --- a/usr.sbin/pim6sd/crc.c +++ b/usr.sbin/pim6sd/crc.c @@ -40,58 +40,64 @@ */ /* CRC implantation : stolen from RFC 2083 section 15.*/ +#include <sys/cdefs.h> +#include "crc.h" + /* Table of CRCs of all 8-bit messages. */ unsigned long crc_table[256]; - + /* Flag: has the table been computed? Initially false. */ int crc_table_computed = 0; + +/* Make the table for a fast CRC. */ -/* Make the table for a fast CRC. */ +static void make_crc_table __P((void)); +static unsigned long update_crc __P((unsigned long, unsigned char *, int)); -void make_crc_table(void) +static void make_crc_table(void) { - unsigned long c; + unsigned long c; int n, k; - for (n = 0; n < 256; n++) + for (n = 0; n < 256; n++) { c = (unsigned long) n; - for (k = 0; k < 8; k++) + for (k = 0; k < 8; k++) { - if (c & 1) + if (c & 1) c = 0xedb88320L ^ (c >> 1); - else - c = c >> 1; - } + else + c = c >> 1; + } crc_table[n] = c; - } + } crc_table_computed = 1; -} - +} + /* Update a running CRC with the bytes buf[0..len-1]--the CRC should be initialized to all 1's, and the transmitted value is the 1's complement of the final running CRC (see the crc() routine below)). */ - -unsigned long update_crc(unsigned long crc, unsigned char *buf, + +static unsigned long update_crc(unsigned long crc, unsigned char *buf, int len) -{ +{ unsigned long c = crc; - int n; - + int n; + if (!crc_table_computed) make_crc_table(); - for (n = 0; n < len; n++) + for (n = 0; n < len; n++) { c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); - } + } return c; -} - +} + /* Return the CRC of the bytes buf[0..len-1]. */ unsigned long crc(unsigned char *buf, int len) -{ +{ return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL; -} +} diff --git a/usr.sbin/pim6sd/crc.h b/usr.sbin/pim6sd/crc.h index e55dbc826bb7a..d1c49f8ab7b95 100644 --- a/usr.sbin/pim6sd/crc.h +++ b/usr.sbin/pim6sd/crc.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -38,11 +36,12 @@ * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef CRC_H #define CRC_H -extern long crc __P((unsigned char *buf, int len)); +extern unsigned long crc __P((unsigned char *buf, int len)); #endif diff --git a/usr.sbin/pim6sd/debug.c b/usr.sbin/pim6sd/debug.c index 9349cceceb398..03f9d8a7fdcdb 100644 --- a/usr.sbin/pim6sd/debug.c +++ b/usr.sbin/pim6sd/debug.c @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -56,6 +54,7 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #include <stdio.h> @@ -94,6 +93,39 @@ static char dumpfilename[] = _PATH_PIM6D_DUMP; static char cachefilename[] = _PATH_PIM6D_CACHE; /* TODO: notused */ static char statfilename[] = _PATH_PIM6D_STAT; +static char *sec2str __P((time_t)); + +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); +} + char * packet_kind(proto, type, code) u_int proto, @@ -264,6 +296,7 @@ fdump(i) { dump_vifs(fp); dump_nbrs(fp); + dump_mldqueriers(fp); dump_pim_mrt(fp); dump_rp_set(fp); (void) fclose(fp); @@ -311,72 +344,95 @@ dump_stat() continue; #endif fprintf(fp, " Mif=%d, PhyIF=%s\n", vifi, v->uv_name); - fprintf(fp, "\t%qu pim6 hello received\n", v->uv_in_pim6_hello); + fprintf(fp, "\t%qu pim6 hello received\n", + (unsigned long long)v->uv_in_pim6_hello); fprintf(fp, "\t%qu pim6 join-prune received\n", - v->uv_in_pim6_join_prune); + (unsigned long long)v->uv_in_pim6_join_prune); fprintf(fp, "\t%qu pim6 bootstrap received\n", - v->uv_in_pim6_bootsrap); - fprintf(fp, "\t%qu pim6 assert received\n", v->uv_in_pim6_assert); + (unsigned long long)v->uv_in_pim6_bootsrap); + fprintf(fp, "\t%qu pim6 assert received\n", + (unsigned long long)v->uv_in_pim6_assert); - fprintf(fp, "\t%qu pim6 hello sent\n", v->uv_out_pim6_hello); + fprintf(fp, "\t%qu pim6 hello sent\n", + (unsigned long long)v->uv_out_pim6_hello); fprintf(fp, "\t%qu pim6 join-prune sent\n", - v->uv_out_pim6_join_prune); + (unsigned long long)v->uv_out_pim6_join_prune); fprintf(fp, "\t%qu pim6 bootstrap sent\n", - v->uv_out_pim6_bootsrap); - fprintf(fp, "\t%qu pim6 assert sent\n", v->uv_out_pim6_assert); + (unsigned long long)v->uv_out_pim6_bootsrap); + fprintf(fp, "\t%qu pim6 assert sent\n", + (unsigned long long)v->uv_out_pim6_assert); - fprintf(fp, "\t%qu MLD query received\n", v->uv_in_mld_query); - fprintf(fp, "\t%qu MLD report received\n", v->uv_in_mld_report); - fprintf(fp, "\t%qu MLD done received\n", v->uv_in_mld_done); + fprintf(fp, "\t%qu MLD query received\n", + (unsigned long long)v->uv_in_mld_query); + fprintf(fp, "\t%qu MLD report received\n", + (unsigned long long)v->uv_in_mld_report); + fprintf(fp, "\t%qu MLD done received\n", + (unsigned long long)v->uv_in_mld_done); - fprintf(fp, "\t%qu MLD query sent\n", v->uv_out_mld_query); - fprintf(fp, "\t%qu MLD report sent\n", v->uv_out_mld_report); - fprintf(fp, "\t%qu MLD done sent\n", v->uv_out_mld_done); + fprintf(fp, "\t%qu MLD query sent\n", + (unsigned long long)v->uv_out_mld_query); + fprintf(fp, "\t%qu MLD report sent\n", + (unsigned long long)v->uv_out_mld_report); + fprintf(fp, "\t%qu MLD done sent\n", + (unsigned long long)v->uv_out_mld_done); - fprintf(fp, "\t%qu forwarding cache miss\n", v->uv_cache_miss); + fprintf(fp, "\t%qu forwarding cache miss\n", + (unsigned long long)v->uv_cache_miss); fprintf(fp, "\t%qu forwarding cache miss and not created\n", - v->uv_cache_notcreated); + (unsigned long long)v->uv_cache_notcreated); - fprintf(fp, "\t%qu PIM neighbor timeouts\n", v->uv_pim6_nbr_timo); - fprintf(fp, "\t%qu MLD listener timeouts\n", v->uv_listener_timo); - fprintf(fp, "\t%qu out-I/F timeouts\n", v->uv_outif_timo); + fprintf(fp, "\t%qu PIM neighbor timeouts\n", + (unsigned long long)v->uv_pim6_nbr_timo); + fprintf(fp, "\t%qu MLD listener timeouts\n", + (unsigned long long)v->uv_listener_timo); + fprintf(fp, "\t%qu MLD querier timeouts\n", + (unsigned long long)v->uv_querier_timo); + fprintf(fp, "\t%qu out-I/F timeouts\n", + (unsigned long long)v->uv_outif_timo); } fprintf(fp, "\npim6sd interface independent statistics\n"); - fprintf(fp, "\t%qu pim6 register received\n", pim6dstat.in_pim6_register); + fprintf(fp, "\t%qu pim6 register received\n", + (unsigned long long)pim6dstat.in_pim6_register); fprintf(fp, "\t%qu pim6 register-stop received\n", - pim6dstat.in_pim6_register_stop); - fprintf(fp, "\t%qu pim6 cand-RP received\n", pim6dstat.in_pim6_cand_rp); - fprintf(fp, "\t%qu pim6 graft received\n", pim6dstat.in_pim6_graft); + (unsigned long long)pim6dstat.in_pim6_register_stop); + fprintf(fp, "\t%qu pim6 cand-RP received\n", + (unsigned long long)pim6dstat.in_pim6_cand_rp); + fprintf(fp, "\t%qu pim6 graft received\n", + (unsigned long long)pim6dstat.in_pim6_graft); fprintf(fp, "\t%qu pim6 graft ack received\n", - pim6dstat.in_pim6_graft_ack); + (unsigned long long)pim6dstat.in_pim6_graft_ack); - fprintf(fp, "\t%qu pim6 register sent\n", pim6dstat.out_pim6_register); + fprintf(fp, "\t%qu pim6 register sent\n", + (unsigned long long)pim6dstat.out_pim6_register); fprintf(fp, "\t%qu pim6 register-stop sent\n", - pim6dstat.out_pim6_register_stop); - fprintf(fp, "\t%qu pim6 cand-RP sent\n", pim6dstat.out_pim6_cand_rp); + (unsigned long long)pim6dstat.out_pim6_register_stop); + fprintf(fp, "\t%qu pim6 cand-RP sent\n", + (unsigned long long)pim6dstat.out_pim6_cand_rp); fprintf(fp, "\t%qu transitions of forwarder initiated SPT\n", - pim6dstat.pim6_trans_spt_forward); + (unsigned long long)pim6dstat.pim6_trans_spt_forward); fprintf(fp, "\t%qu transitions of RP initiated SPT\n", - pim6dstat.pim6_trans_spt_rp); + (unsigned long long)pim6dstat.pim6_trans_spt_rp); fprintf(fp, "\t%qu pim6 bootstrap timeouts\n", - pim6dstat.pim6_bootstrap_timo); + (unsigned long long)pim6dstat.pim6_bootstrap_timo); fprintf(fp, "\t%qu pim6 RP group entry timeouts\n", - pim6dstat.pim6_rpgrp_timo); + (unsigned long long)pim6dstat.pim6_rpgrp_timo); fprintf(fp, "\t%qu pim6 routing entry timeouts\n", - pim6dstat.pim6_rtentry_timo); + (unsigned long long)pim6dstat.pim6_rtentry_timo); - fprintf(fp, "\t%qu kernel cache additions\n", pim6dstat.kern_add_cache); + fprintf(fp, "\t%qu kernel cache additions\n", + (unsigned long long)pim6dstat.kern_add_cache); fprintf(fp, "\t%qu kernel cache addition failures\n", - pim6dstat.kern_add_cache_fail); - fprintf(fp, "\t%qu kernel cache deletions\n", pim6dstat.kern_del_cache); + (unsigned long long)pim6dstat.kern_add_cache_fail); + fprintf(fp, "\t%qu kernel cache deletions\n", + (unsigned long long)pim6dstat.kern_del_cache); fprintf(fp, "\t%qu kernel cache deletion failures\n", - pim6dstat.kern_del_cache_fail); + (unsigned long long)pim6dstat.kern_del_cache_fail); fprintf(fp, "\t%qu failures of getting kernel cache\n", - pim6dstat.kern_sgcnt_fail); + (unsigned long long)pim6dstat.kern_sgcnt_fail); fclose(fp); } @@ -425,6 +481,8 @@ dump_vifs(fp) fprintf(fp, " DR"); if (v->uv_flags & VIFF_PIM_NBR) fprintf(fp, " PIM"); + if (v->uv_flags & VIFF_QUERIER) + fprintf(fp, " QRY"); #if 0 /* impossible */ if (v->uv_flags & VIFF_DVMRP_NBR) { @@ -432,7 +490,7 @@ dump_vifs(fp) } #endif if (v->uv_flags & VIFF_NONBRS) - fprintf(fp, " %-12s", "NO-NBR"); + fprintf(fp, " NO-NBR"); fprintf(fp, "\n"); } @@ -462,7 +520,7 @@ dump_nbrs(fp) int first = 1; fprintf(fp, " %-3u %6s", vifi, - (v->uv_flags & MIFF_REGISTER)?"regist": + (v->uv_flags & MIFF_REGISTER) ? "regist": v->uv_name); for (; n != NULL; n = n->next) { if (first) @@ -479,6 +537,35 @@ dump_nbrs(fp) fprintf(fp, "\n"); } +void +dump_mldqueriers(fp) + FILE *fp; +{ + struct uvif *v; + vifi_t vifi; + time_t now; + + fprintf(fp, "MLD Querier List\n"); + fprintf(fp, " %-3s %6s %-40s %-5s %15s\n", + "Mif", "PhyIF", "Address", "Timer", "Last"); + (void)time(&now); + + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { + if (v->uv_querier) { + fprintf(fp, " %-3u %6s", vifi, + (v->uv_flags & MIFF_REGISTER) ? "regist": + v->uv_name); + + fprintf(fp, " %-40s %5lu %15s\n", + sa6_fmt(&v->uv_querier->al_addr), + (u_long)v->uv_querier->al_timer, + sec2str(now - v->uv_querier->al_ctime)); + } + } + + fprintf(fp, "\n"); +} + /* * Log errors and other messages to the system log daemon and to stderr, * according to the severity of the message and the current debug level. For @@ -532,7 +619,8 @@ va_dcl if (!debug) fprintf(fp, "%s: ", progname); fprintf(fp, "%02d:%02d:%02d.%03ld %s", thyme->tm_hour, - thyme->tm_min, thyme->tm_sec, now.tv_usec / 1000, msg); + thyme->tm_min, thyme->tm_sec, (long int)now.tv_usec / 1000, + msg); if (syserr == 0) fprintf(fp, "\n"); else @@ -663,7 +751,7 @@ dump_pim_mrt(fp) fprintf(fp, "Asserted oifs: %-20s\n", asserted_oifs); fprintf(fp, "Outgoing oifs: %-20s\n", oifs); fprintf(fp, "Incoming : %-20s\n", incoming_iif); - + fprintf(fp, "Upstream nbr: %s\n", r->upstream ? inet6_fmt(&r->upstream->address.sin6_addr) : "NONE"); diff --git a/usr.sbin/pim6sd/debug.h b/usr.sbin/pim6sd/debug.h index 094ffd1d1e24b..683aada509ff3 100644 --- a/usr.sbin/pim6sd/debug.h +++ b/usr.sbin/pim6sd/debug.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,104 +32,105 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef DEBUG_H -#define DEBUG_H +#define DEBUG_H #include <sys/types.h> #include <stdio.h> extern unsigned long debug; extern int log_nmsgs; extern FILE *log_fp; -#define IF_DEBUG(l) if (debug && debug & (l)) +#define IF_DEBUG(l) if (debug && debug & (l)) -#define LOG_MAX_MSGS 20 /* if > 20/minute then shut up for a while */ -#define LOG_SHUT_UP 600 /* shut up for 10 minutes */ +#define LOG_MAX_MSGS 20 /* if > 20/minute then shut up for a while */ +#define LOG_SHUT_UP 600 /* shut up for 10 minutes */ /* Debug values definition */ /* DVMRP reserved for future use */ -#define DEBUG_DVMRP_PRUNE 0x00000001 -#define DEBUG_DVMRP_ROUTE 0x00000002 -#define DEBUG_DVMRP_PEER 0x00000004 -#define DEBUG_DVMRP_TIMER 0x00000008 -#define DEBUG_DVMRP_DETAIL 0x01000000 -#define DEBUG_DVMRP ( DEBUG_DVMRP_PRUNE | DEBUG_DVMRP_ROUTE | \ +#define DEBUG_DVMRP_PRUNE 0x00000001 +#define DEBUG_DVMRP_ROUTE 0x00000002 +#define DEBUG_DVMRP_PEER 0x00000004 +#define DEBUG_DVMRP_TIMER 0x00000008 +#define DEBUG_DVMRP_DETAIL 0x01000000 +#define DEBUG_DVMRP ( DEBUG_DVMRP_PRUNE | DEBUG_DVMRP_ROUTE | \ DEBUG_DVMRP_PEER ) /* MLD related */ -#define DEBUG_MLD_PROTO 0x00000010 -#define DEBUG_MLD_TIMER 0x00000020 -#define DEBUG_MLD_MEMBER 0x00000040 -#define DEBUG_MEMBER DEBUG_MLD_MEMBER -#define DEBUG_MLD ( DEBUG_MLD_PROTO | DEBUG_MLD_TIMER | \ +#define DEBUG_MLD_PROTO 0x00000010 +#define DEBUG_MLD_TIMER 0x00000020 +#define DEBUG_MLD_MEMBER 0x00000040 +#define DEBUG_MEMBER DEBUG_MLD_MEMBER +#define DEBUG_MLD ( DEBUG_MLD_PROTO | DEBUG_MLD_TIMER | \ DEBUG_MLD_MEMBER ) /* Misc */ -#define DEBUG_TRACE 0x00000080 -#define DEBUG_TIMEOUT 0x00000100 -#define DEBUG_PKT 0x00000200 +#define DEBUG_TRACE 0x00000080 +#define DEBUG_TIMEOUT 0x00000100 +#define DEBUG_PKT 0x00000200 /* Kernel related */ -#define DEBUG_IF 0x00000400 -#define DEBUG_KERN 0x00000800 -#define DEBUG_MFC 0x00001000 -#define DEBUG_RSRR 0x00002000 +#define DEBUG_IF 0x00000400 +#define DEBUG_KERN 0x00000800 +#define DEBUG_MFC 0x00001000 +#define DEBUG_RSRR 0x00002000 /* PIM related */ -#define DEBUG_PIM_HELLO 0x00004000 -#define DEBUG_PIM_REGISTER 0x00008000 -#define DEBUG_PIM_JOIN_PRUNE 0x00010000 -#define DEBUG_PIM_BOOTSTRAP 0x00020000 -#define DEBUG_PIM_ASSERT 0x00040000 -#define DEBUG_PIM_CAND_RP 0x00080000 -#define DEBUG_PIM_MRT 0x00100000 -#define DEBUG_PIM_TIMER 0x00200000 -#define DEBUG_PIM_RPF 0x00400000 -#define DEBUG_RPF DEBUG_PIM_RPF -#define DEBUG_PIM_DETAIL 0x00800000 -#define DEBUG_PIM ( DEBUG_PIM_HELLO | DEBUG_PIM_REGISTER | \ +#define DEBUG_PIM_HELLO 0x00004000 +#define DEBUG_PIM_REGISTER 0x00008000 +#define DEBUG_PIM_JOIN_PRUNE 0x00010000 +#define DEBUG_PIM_BOOTSTRAP 0x00020000 +#define DEBUG_PIM_ASSERT 0x00040000 +#define DEBUG_PIM_CAND_RP 0x00080000 +#define DEBUG_PIM_MRT 0x00100000 +#define DEBUG_PIM_TIMER 0x00200000 +#define DEBUG_PIM_RPF 0x00400000 +#define DEBUG_RPF DEBUG_PIM_RPF +#define DEBUG_PIM_DETAIL 0x00800000 +#define DEBUG_PIM ( DEBUG_PIM_HELLO | DEBUG_PIM_REGISTER | \ DEBUG_PIM_JOIN_PRUNE | DEBUG_PIM_BOOTSTRAP | \ DEBUG_PIM_ASSERT | DEBUG_PIM_CAND_RP | \ DEBUG_PIM_MRT | DEBUG_PIM_TIMER | \ - DEBUG_PIM_RPF ) + DEBUG_PIM_RPF ) -#define DEBUG_MRT ( DEBUG_DVMRP_ROUTE | DEBUG_PIM_MRT ) -#define DEBUG_NEIGHBORS ( DEBUG_DVMRP_PEER | DEBUG_PIM_HELLO ) -#define DEBUG_TIMER ( DEBUG_MLD_TIMER | DEBUG_DVMRP_TIMER | \ +#define DEBUG_MRT ( DEBUG_DVMRP_ROUTE | DEBUG_PIM_MRT ) +#define DEBUG_NEIGHBORS ( DEBUG_DVMRP_PEER | DEBUG_PIM_HELLO ) +#define DEBUG_TIMER ( DEBUG_MLD_TIMER | DEBUG_DVMRP_TIMER | \ DEBUG_PIM_TIMER ) -#define DEBUG_ASSERT ( DEBUG_PIM_ASSERT ) +#define DEBUG_ASSERT ( DEBUG_PIM_ASSERT ) /* CONFIG related */ -#define DEBUG_CONF 0x01000000 +#define DEBUG_CONF 0x01000000 -#define DEBUG_ALL 0xffffffff -#define DEBUG_SWITCH 0x80000000 +#define DEBUG_ALL 0xffffffff +#define DEBUG_SWITCH 0x80000000 -#define DEBUG_DEFAULT 0xffffffff/* default if "-d" given without value */ +#define DEBUG_DEFAULT 0xffffffff/* default if "-d" given without value */ #if defined(YIPS_DEBUG) -#define YIPSDEBUG(lev,arg) if ((debug & (lev)) == (lev)) { arg; } +#define YIPSDEBUG(lev,arg) if ((debug & (lev)) == (lev)) { arg; } #else -#define YIPSDEBUG(lev,arg) +#define YIPSDEBUG(lev,arg) #endif /* defined(YIPS_DEBUG) */ extern char *packet_kind __P((u_int proto, u_int type, @@ -146,8 +145,9 @@ extern void fdump __P((int i)); extern void cdump __P((int i)); extern void dump_vifs __P((FILE *fp)); extern void dump_nbrs __P((FILE *fp)); +extern void dump_mldqueriers __P((FILE *fp)); extern void dump_pim_mrt __P((FILE *fp)); extern int dump_rp_set __P((FILE *fp)); -extern void dump_stat __P(()); +extern void dump_stat __P((void)); #endif diff --git a/usr.sbin/pim6sd/defs.h b/usr.sbin/pim6sd/defs.h index b9c3389e4f74b..58ffe6b90062d 100644 --- a/usr.sbin/pim6sd/defs.h +++ b/usr.sbin/pim6sd/defs.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,26 +32,27 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef DEFS_H -#define DEFS_H +#define DEFS_H #include <sys/types.h> #define TRUE 1 #define FALSE 0 -#define ELSE else /* To make emacs cc-mode happy */ +#define ELSE else /* To make emacs cc-mode happy */ #define max( a , b ) ( ( a )<( b )?( b ):( a ) ) @@ -64,12 +63,12 @@ int register_input_handler __P((int fd,ihfunc_t func)); /* CONFIGCONFIGCONFIGCONFIG */ -#define HAVE_ROUTING_SOCKETS -#define HAVE_SA_LEN -#define RANDOM() random() +#define HAVE_ROUTING_SOCKETS +#define HAVE_SA_LEN +#define RANDOM() random() -#define PRINTF printf -#define ALL_MCAST_GROUPS_LENGTH 8 +#define PRINTF printf +#define ALL_MCAST_GROUPS_LENGTH 8 typedef u_int u_int32; diff --git a/usr.sbin/pim6sd/inet6.c b/usr.sbin/pim6sd/inet6.c index ff34532500f80..220a443f3253c 100644 --- a/usr.sbin/pim6sd/inet6.c +++ b/usr.sbin/pim6sd/inet6.c @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,17 +32,20 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ +#include <sys/types.h> +#include <sys/socket.h> #include <stdio.h> #include <netdb.h> #include <string.h> @@ -186,30 +187,38 @@ inet6_match_prefix(sa1, sa2, mask) return (1); } -char * -inet6_fmt(struct in6_addr * addr) +char * +sa6_fmt(struct sockaddr_in6 *sa6) { static char ip6buf[8][MAXHOSTNAMELEN]; static int ip6round = 0; - char *cp; - struct sockaddr_in6 sa6; int flags = NI_WITHSCOPEID; + char *cp; ip6round = (ip6round + 1) & 7; cp = ip6buf[ip6round]; + if (numerichost) + flags |= NI_NUMERICHOST; + getnameinfo((struct sockaddr *)sa6, sa6->sin6_len, cp, MAXHOSTNAMELEN, + NULL, 0, flags); + + return(cp); +} + +char * +inet6_fmt(struct in6_addr * addr) +{ + struct sockaddr_in6 sa6; + + memset(&sa6, 0, sizeof(sa6)); sa6.sin6_len = sizeof(sa6); sa6.sin6_family = AF_INET6; sa6.sin6_addr = *addr; sa6.sin6_scope_id = 0; /* XXX */ - if (numerichost) - flags |= NI_NUMERICHOST; - getnameinfo((struct sockaddr *)&sa6, sa6.sin6_len, cp, MAXHOSTNAMELEN, - NULL, 0, flags); - - return(cp); + return(sa6_fmt(&sa6)); } char * diff --git a/usr.sbin/pim6sd/inet6.h b/usr.sbin/pim6sd/inet6.h index 21ba6dc29e621..c7225f6fa40c9 100644 --- a/usr.sbin/pim6sd/inet6.h +++ b/usr.sbin/pim6sd/inet6.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,26 +32,27 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef INET6_H -#define INET6_H +#define INET6_H #include "vif.h" extern int numerichost; extern int inet6_equal __P((struct sockaddr_in6 *sa1, - struct sockaddr_in6 *sa2)); + struct sockaddr_in6 *sa2)); extern int inet6_lessthan __P((struct sockaddr_in6 *sa1, struct sockaddr_in6 *sa2)); extern int inet6_localif_address __P((struct sockaddr_in6 *sa, @@ -66,9 +65,10 @@ extern int inet6_match_prefix __P((struct sockaddr_in6 *sa1, extern int inet6_mask2plen __P((struct in6_addr *mask)); extern int inet6_uvif2scopeid __P((struct sockaddr_in6 *sa, struct uvif *v)); extern int inet6_valid_host __P((struct sockaddr_in6 *addr)); +extern char *sa6_fmt __P((struct sockaddr_in6 *sa6)); extern char *inet6_fmt __P((struct in6_addr *addr)); extern char *ifindex2str __P((int ifindex)); -extern char *net6name __P((struct in6_addr *prefix, +extern char *net6name __P((struct in6_addr *prefix, struct in6_addr *mask)); diff --git a/usr.sbin/pim6sd/kern.c b/usr.sbin/pim6sd/kern.c index 73f610d72d9e1..44c415a632678 100644 --- a/usr.sbin/pim6sd/kern.c +++ b/usr.sbin/pim6sd/kern.c @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,15 +36,16 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #include <sys/time.h> @@ -69,16 +68,17 @@ #include "vif.h" #include "mrt.h" #include "debug.h" +#include "kern.h" -/* +/* * Open/init the multicast routing in the kernel and sets the MRT_ASSERT * flag in the kernel. * */ -void +void k_init_pim(int socket) { int v = 1; @@ -110,12 +110,12 @@ k_stop_pim(socket) } -/* +/* * Set the socket receiving buffer. `bufsize` is the preferred size, * `minsize` is the smallest acceptable size. - */ + */ -void +void k_set_rcvbuf(int socket, int bufsize, int minsize) { int delta = bufsize / 2; @@ -125,7 +125,7 @@ k_set_rcvbuf(int socket, int bufsize, int minsize) * Set the socket buffer. If we can't set it as large as we * want, search around to try to find the highest acceptable * value. The highest acceptable value being smaller than - * minsize is a fatal error. + * minsize is a fatal error. */ @@ -157,12 +157,12 @@ k_set_rcvbuf(int socket, int bufsize, int minsize) log(LOG_DEBUG,0,"Buffer reception size for socket %d : %d in %d iterations",socket, bufsize, iter); } -/* +/* * Set the default Hop Limit for the multicast packets outgoing from this * socket. - */ + */ -void +void k_set_hlim(int socket, int h) { int hlim = h; @@ -177,7 +177,7 @@ k_set_hlim(int socket, int h) */ -void +void k_set_loop(int socket, int flag) { u_int loop; @@ -190,10 +190,10 @@ k_set_loop(int socket, int flag) /* * Set the IPV6_MULTICAST_IF option on local interface which has the * specified index. - */ + */ -void +void k_set_if(int socket, u_int ifindex) { if (setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_IF, @@ -205,9 +205,9 @@ k_set_if(int socket, u_int ifindex) /* * Join a multicast grp group on local interface ifa. - */ + */ -void +void k_join(int socket, struct in6_addr * grp, u_int ifindex) { struct ipv6_mreq mreq; @@ -223,9 +223,9 @@ k_join(int socket, struct in6_addr * grp, u_int ifindex) /* * Leave a multicats grp group on local interface ifa. - */ + */ -void +void k_leave(int socket, struct in6_addr * grp, u_int ifindex) { struct ipv6_mreq mreq; @@ -239,11 +239,11 @@ k_leave(int socket, struct in6_addr * grp, u_int ifindex) inet6_fmt(grp), ifindex2str(ifindex)); } -/* +/* * Add a virtual interface in the kernel. */ -void +void k_add_vif(int socket, vifi_t vifi, struct uvif * v) { struct mif6ctl mc; @@ -266,7 +266,7 @@ k_add_vif(int socket, vifi_t vifi, struct uvif * v) * Delete a virtual interface in the kernel. */ -void +void k_del_vif(int socket, vifi_t vifi) { if (setsockopt(socket, IPPROTO_IPV6, MRT6_DEL_MIF, @@ -276,9 +276,9 @@ k_del_vif(int socket, vifi_t vifi) /* * Delete all MFC entries for particular routing entry from the kernel. - */ + */ -int +int k_del_mfc(int socket, struct sockaddr_in6 * source, struct sockaddr_in6 * group) { struct mf6cctl mc; @@ -290,7 +290,7 @@ k_del_mfc(int socket, struct sockaddr_in6 * source, struct sockaddr_in6 * group) if (setsockopt(socket, IPPROTO_IPV6, MRT6_DEL_MFC, (char *) &mc, sizeof(mc)) < 0) { pim6dstat.kern_del_cache_fail++; - log(LOG_WARNING, errno, "setsockopt MRT6_DEL_MFC"); + log(LOG_WARNING, errno, "setsockopt MRT6_DEL_MFC"); return FALSE; } @@ -359,7 +359,7 @@ k_chg_mfc(socket, source, group, iif, oifs, rp_addr) * XXX: TODO: currently not used, but keep just in case we need it later. */ -int +int k_get_vif_count(vifi, retval) vifi_t vifi; struct vif_count *retval; diff --git a/usr.sbin/pim6sd/kern.h b/usr.sbin/pim6sd/kern.h index f58503c4cadf6..13ba8e8c5e85d 100644 --- a/usr.sbin/pim6sd/kern.h +++ b/usr.sbin/pim6sd/kern.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,20 +32,21 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ -#ifndef KERN_H -#define KERN_H +#ifndef KERN_H +#define KERN_H #include "vif.h" #include "mrt.h" @@ -59,12 +58,12 @@ extern void k_join __P((int socket, struct in6_addr *grp, u_int ifindex)); extern void k_leave __P((int socket, struct in6_addr *grp, u_int ifindex)); -extern void k_init_pim __P(()); -extern void k_stop_pim __P(()); +extern void k_init_pim __P((int)); +extern void k_stop_pim __P((int)); extern int k_del_mfc __P((int socket, struct sockaddr_in6 *source, struct sockaddr_in6 *group)); extern int k_chg_mfc __P((int socket, struct sockaddr_in6 *source, - struct sockaddr_in6 *group, vifi_t iif, + struct sockaddr_in6 *group, vifi_t iif, if_set *oifs, struct sockaddr_in6 *rp_addr)); extern void k_add_vif __P((int socket, vifi_t vifi, struct uvif *v)); extern void k_del_vif __P((int socket, vifi_t vifi)); diff --git a/usr.sbin/pim6sd/main.c b/usr.sbin/pim6sd/main.c index 153d528df12f1..00242860869bc 100644 --- a/usr.sbin/pim6sd/main.c +++ b/usr.sbin/pim6sd/main.c @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,12 +36,12 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * @@ -56,6 +54,7 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #include <sys/param.h> @@ -85,7 +84,7 @@ char configfilename[256] = _PATH_PIM6D_CONF; char versionstring[100]; char logfilename[256] = _PATH_PIM6D_LOGFILE; -/* TODO: not used +/* TODO: not used static char genidfilename[] = _PATH_PIM6D_GENID; */ static char pidfilename[] = _PATH_PIM6D_PID; @@ -96,15 +95,15 @@ char *progname; static int foreground = 0; static int sighandled = 0; -#define GOT_SIGINT 0x01 -#define GOT_SIGHUP 0x02 -#define GOT_SIGUSR1 0x04 -#define GOT_SIGUSR2 0x08 -#define GOT_SIGALRM 0x10 -#define GOT_SIGINFO 0x20 +#define GOT_SIGINT 0x01 +#define GOT_SIGHUP 0x02 +#define GOT_SIGUSR1 0x04 +#define GOT_SIGUSR2 0x08 +#define GOT_SIGALRM 0x10 +#define GOT_SIGINFO 0x20 -#define NHANDLERS 3 +#define NHANDLERS 3 static struct ihandler { @@ -274,7 +273,7 @@ main(argc, argv) { no=1; p++; - } + } len = strlen(p); for (i = 0, d = debugnames; i < sizeof(debugnames) / sizeof(debugnames[0]); @@ -547,20 +546,20 @@ usage: } if ((n = select(nfds, &rfds, NULL, NULL, timeout)) < 0) { - if (errno != EINTR) + if (errno != EINTR) log(LOG_WARNING, errno, "select failed"); continue; } /* * Handle timeout queue. - * + * * If select + packet processing took more than 1 second, or if there is * a timeout pending, age the timeout queue. - * + * * If not, collect usec in difftime to make sure that the time doesn't * drift too badly. - * + * * If the timeout handlers took more than 1 second, age the timeout * queue again. XXX This introduces the potential for infinite * loops! @@ -637,7 +636,7 @@ usage: * initial- ization. This repetition after a short interval is desirable for * quickly building up topology and membership information in the presence of * possible packet loss. - * + * * 'virtual_time' advances at a rate that is only a crude approximation of real * time, because it does not take into account any time spent processing, and * because the timer intervals are sometimes shrunk by a random amount to @@ -677,9 +676,9 @@ cleanup() * TODO: XXX (not in the spec): if I am the BSR, somehow inform the other * routers I am going down and need to elect another BSR? (probably by * sending a the Cand-RP-set with my_priority=LOWEST?) - * - */ - + * + */ + k_stop_pim(mld6_socket); } @@ -736,7 +735,7 @@ restart(i) * reset all the entries */ /* - * TODO: delete? + * TODO: delete? free_all_routes(); */ diff --git a/usr.sbin/pim6sd/mld6.c b/usr.sbin/pim6sd/mld6.c index 9c9c1096b889b..55ae6e21611ee 100644 --- a/usr.sbin/pim6sd/mld6.c +++ b/usr.sbin/pim6sd/mld6.c @@ -57,8 +57,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -66,15 +64,16 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #include <sys/types.h> @@ -118,11 +117,12 @@ static struct msghdr sndmh, static struct iovec sndiov[2]; static struct iovec rcviov[2]; static struct sockaddr_in6 from; -static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int))]; +static u_char *rcvcmsgbuf = NULL; +static int rcvcmsglen; + #ifndef USE_RFC2292BIS u_int8_t raopt[IP6OPT_RTALERT_LEN]; -#endif +#endif static char *sndcmsgbuf; static int ctlbuflen = 0; static u_short rtalert_code; @@ -131,9 +131,11 @@ static u_short rtalert_code; static void mld6_read __P((int i, fd_set * fds)); static void accept_mld6 __P((int len)); +static void make_mld6_msg __P((int, int, struct sockaddr_in6 *, + struct sockaddr_in6 *, struct in6_addr *, int, int, int, int)); #ifndef IP6OPT_ROUTER_ALERT /* XXX to be compatible older systems */ -#define IP6OPT_ROUTER_ALERT IP6OPT_RTALERT +#define IP6OPT_ROUTER_ALERT IP6OPT_RTALERT #endif /* @@ -147,10 +149,15 @@ init_mld6() rtalert_code = htons(IP6OPT_RTALERT_MLD); if (!mld6_recv_buf && (mld6_recv_buf = malloc(RECV_BUF_SIZE)) == NULL) - log(LOG_ERR, 0, "malloca failed"); + log(LOG_ERR, 0, "malloc failed"); if (!mld6_send_buf && (mld6_send_buf = malloc(RECV_BUF_SIZE)) == NULL) - log(LOG_ERR, 0, "malloca failed"); + log(LOG_ERR, 0, "malloc failed"); + rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + if (rcvcmsgbuf == NULL && (rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) + log(LOG_ERR, 0,"malloc failed"); + IF_DEBUG(DEBUG_KERN) log(LOG_DEBUG,0,"%d octets allocated for the emit/recept buffer mld6",RECV_BUF_SIZE); @@ -189,7 +196,7 @@ init_mld6() if (setsockopt(mld6_socket, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on)) < 0) log(LOG_ERR, errno, "setsockopt(IPV6_PKTINFO)"); -#endif +#endif on = 1; /* specify to tell value of hoplimit field of received IP6 hdr */ @@ -201,7 +208,7 @@ init_mld6() if (setsockopt(mld6_socket, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on)) < 0) log(LOG_ERR, errno, "setsockopt(IPV6_HOPLIMIT)"); -#endif +#endif /* initialize msghdr for receiving packets */ rcviov[0].iov_base = (caddr_t) mld6_recv_buf; @@ -211,7 +218,7 @@ init_mld6() rcvmh.msg_iov = rcviov; rcvmh.msg_iovlen = 1; rcvmh.msg_control = (caddr_t) rcvcmsgbuf; - rcvmh.msg_controllen = sizeof(rcvcmsgbuf); + rcvmh.msg_controllen = rcvcmsglen; /* initialize msghdr for sending packets */ sndiov[0].iov_base = (caddr_t)mld6_send_buf; @@ -223,7 +230,7 @@ init_mld6() raopt[0] = IP6OPT_ROUTER_ALERT; raopt[1] = IP6OPT_RTALERT_LEN - 2; memcpy(&raopt[2], (caddr_t) & rtalert_code, sizeof(u_short)); -#endif +#endif /* register MLD message handler */ if (register_input_handler(mld6_socket, mld6_read) < 0) @@ -268,19 +275,6 @@ int recvlen; int ifindex = 0; struct sockaddr_in6 *src = (struct sockaddr_in6 *) rcvmh.msg_name; - /* - * If control length is zero, it must be an upcall from the kernel - * multicast forwarding engine. - * XXX: can we trust it? - */ - if (rcvmh.msg_controllen == 0) { - /* XXX: msg_controllen must be reset in this case. */ - rcvmh.msg_controllen = sizeof(rcvcmsgbuf); - - process_kernel_call(); - return; - } - if (recvlen < sizeof(struct mld6_hdr)) { log(LOG_WARNING, 0, @@ -289,6 +283,20 @@ int recvlen; return; } mldh = (struct mld6_hdr *) rcvmh.msg_iov[0].iov_base; + + /* + * Packets sent up from kernel to daemon have ICMPv6 type = 0. + * Note that we set filters on the mld6_socket, so we should never + * see a "normal" ICMPv6 packet with type 0 of ICMPv6 type. + */ + if (mldh->mld6_type == 0) { + /* XXX: msg_controllen must be reset in this case. */ + rcvmh.msg_controllen = rcvcmsglen; + + process_kernel_call(); + return; + } + group = &mldh->mld6_addr; /* extract optional information via Advanced API */ @@ -418,7 +426,7 @@ make_mld6_msg(type, code, src, dst, group, ifindex, delay, datalen, alert) datalen = sizeof(struct mld6_hdr); break; } - + bzero(mhp, sizeof(*mhp)); mhp->mld6_type = type; mhp->mld6_code = code; @@ -440,10 +448,11 @@ make_mld6_msg(type, code, src, dst, group, ifindex, delay, datalen, alert) log(LOG_ERR, 0, "inet6_opt_append(0) failed"); if ((hbhlen = inet6_opt_finish(NULL, 0, hbhlen)) == -1) log(LOG_ERR, 0, "inet6_opt_finish(0) failed"); + ctllen += CMSG_SPACE(hbhlen); #else /* old advanced API */ - hbhlen = inet6_option_space(sizeof(raopt)); + hbhlen = inet6_option_space(sizeof(raopt)); + ctllen += hbhlen; #endif - ctllen += CMSG_SPACE(hbhlen); } /* extend ancillary data space (if necessary) */ if (ctlbuflen < ctllen) { @@ -505,7 +514,7 @@ make_mld6_msg(type, code, src, dst, group, ifindex, delay, datalen, alert) if (inet6_option_append(cmsgp, raopt, 4, 0)) log(LOG_ERR, 0, /* assert */ "make_mld6_msg: inet6_option_append failed"); -#endif +#endif cmsgp = CMSG_NXTHDR(&sndmh, cmsgp); } } @@ -525,7 +534,7 @@ send_mld6(type, code, src, dst, group, index, delay, datalen, alert) { int setloop = 0; struct sockaddr_in6 *dstp; - + make_mld6_msg(type, code, src, dst, group, index, delay, datalen, alert); dstp = (struct sockaddr_in6 *)sndmh.msg_name; if (IN6_ARE_ADDR_EQUAL(&dstp->sin6_addr, &allnodes_group.sin6_addr)) { @@ -546,7 +555,7 @@ send_mld6(type, code, src, dst, group, index, delay, datalen, alert) k_set_loop(mld6_socket, FALSE); return; } - + IF_DEBUG(DEBUG_PKT|debug_kind(IPPROTO_IGMP, type, 0)) log(LOG_DEBUG, 0, "SENT %s from %-15s to %s", packet_kind(IPPROTO_ICMPV6, type, 0), diff --git a/usr.sbin/pim6sd/mld6.h b/usr.sbin/pim6sd/mld6.h index dcc43f1b792a0..0f970619c9ac9 100644 --- a/usr.sbin/pim6sd/mld6.h +++ b/usr.sbin/pim6sd/mld6.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,47 +32,51 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef MLD6_H -#define MLD6_H +#define MLD6_H #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> -#define RECV_BUF_SIZE 64*1024 -#define SO_RECV_BUF_SIZE_MAX 256*1024 -#define SO_RECV_BUF_SIZE_MIN 48*1024 -#define MINHLIM 1 +#define RECV_BUF_SIZE 64*1024 +#define SO_RECV_BUF_SIZE_MAX 256*1024 +#define SO_RECV_BUF_SIZE_MIN 48*1024 +#define MINHLIM 1 /* * Constans for Multicast Listener Discovery protocol for IPv6. */ -#define MLD6_ROBUSTNESS_VARIABLE 2 -#define MLD6_QUERY_INTERVAL 125 /* in seconds */ -#define MLD6_QUERY_RESPONSE_INTERVAL 10000 /* in milliseconds */ +#define MLD6_ROBUSTNESS_VARIABLE 2 +#define MLD6_QUERY_INTERVAL 125 /* in seconds */ +#define MLD6_QUERY_RESPONSE_INTERVAL 10000 /* in milliseconds */ #ifndef MLD6_TIMER_SCALE -#define MLD6_TIMER_SCALE 1000 +#define MLD6_TIMER_SCALE 1000 #endif -#define MLD6_LISTENER_INTERVAL (MLD6_ROBUSTNESS_VARIABLE * \ +#define MLD6_LISTENER_INTERVAL (MLD6_ROBUSTNESS_VARIABLE * \ MLD6_QUERY_INTERVAL + \ MLD6_QUERY_RESPONSE_INTERVAL / MLD6_TIMER_SCALE) -#define MLD6_LAST_LISTENER_QUERY_INTERVAL 1000 /* in milliseconds */ -#define MLD6_LAST_LISTENER_QUERY_COUNT MLD6_ROBUSTNESS_VARIABLE +#define MLD6_LAST_LISTENER_QUERY_INTERVAL 1000 /* in milliseconds */ +#define MLD6_LAST_LISTENER_QUERY_COUNT MLD6_ROBUSTNESS_VARIABLE +#define MLD6_OTHER_QUERIER_PRESENT_INTERVAL (MLD6_ROBUSTNESS_VARIABLE * \ + MLD6_QUERY_INTERVAL + \ + MLD6_QUERY_RESPONSE_INTERVAL / (2 * MLD6_TIMER_SCALE)) extern int mld6_socket; extern char *mld6_recv_buf; @@ -82,7 +84,7 @@ extern struct sockaddr_in6 allrouters_group; extern struct sockaddr_in6 allnodes_group; extern char *mld6_send_buf; -void init_mld6 __P(()); +void init_mld6 __P((void)); void send_mld6 __P((int type, int code, struct sockaddr_in6 *src, struct sockaddr_in6 *dst, struct in6_addr *group, int index, int delay, int datalen, int alert)); diff --git a/usr.sbin/pim6sd/mld6_proto.c b/usr.sbin/pim6sd/mld6_proto.c index 4533aac4e5d79..400be862166d4 100644 --- a/usr.sbin/pim6sd/mld6_proto.c +++ b/usr.sbin/pim6sd/mld6_proto.c @@ -57,8 +57,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -66,12 +64,12 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * @@ -93,6 +91,7 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #include <sys/param.h> @@ -113,6 +112,8 @@ #include "callout.h" #include "timer.h" +#include "mld6_proto.h" + extern struct in6_addr in6addr_any; typedef struct @@ -130,7 +131,7 @@ static void DelVif __P((void *arg)); static int SetTimer __P((int mifi, struct listaddr * g)); static int DeleteTimer __P((int id)); static void SendQuery __P((void *arg)); -static int SetQueryTimer +static int SetQueryTimer __P((struct listaddr * g, int mifi, int to_expire, int q_time)); @@ -177,37 +178,34 @@ accept_listener_query(src, dst, group, tmo) register struct uvif *v; struct sockaddr_in6 group_sa = {sizeof(group_sa), AF_INET6}; - /* Ignore my own membership query */ + /* Ignore my own listener query */ if (local_address(src) != NO_VIF) return; - if ((mifi = find_vif_direct(src)) == NO_VIF) - { + if ((mifi = find_vif_direct(src)) == NO_VIF) { IF_DEBUG(DEBUG_MLD) log(LOG_INFO, 0, "accept_listener_query: can't find a mif"); return; } - + v = &uvifs[mifi]; + v->uv_in_mld_query++; IF_DEBUG(DEBUG_MLD) log(LOG_DEBUG, 0, - "accepting multicast listener query: " + "accepting multicast listener query on %s: " "src %s, dst %s, grp %s", + v->uv_name, inet6_fmt(&src->sin6_addr), inet6_fmt(dst), inet6_fmt(group)); - v = &uvifs[mifi]; - v->uv_in_mld_query++; - - if (v->uv_querier == NULL || inet6_equal(&v->uv_querier->al_addr, src)) - { + if (v->uv_querier == NULL || !inet6_equal(&v->uv_querier->al_addr, src)) { /* - * This might be: - A query from a new querier, with a lower source - * address than the current querier (who might be me) - A query from - * a new router that just started up and doesn't know who the querier - * is. - A query from the current querier + * This might be: + * - A query from a new querier, with a lower source address than + * the current querier (who might be me). + * - A query from a new router that just started up and doesn't know + * who the querier is. */ - if (inet6_lessthan(src, (v->uv_querier ? &v->uv_querier->al_addr : &v->uv_linklocal->pa_addr))) { @@ -218,22 +216,11 @@ accept_listener_query(src, dst, group, tmo) v->uv_querier ? inet6_fmt(&v->uv_querier->al_addr.sin6_addr) : "me", mifi); - if (!v->uv_querier) - { + if (!v->uv_querier) { /* this should be impossible... */ v->uv_querier = (struct listaddr *)malloc(sizeof(struct listaddr)); - v->uv_querier->al_next = (struct listaddr *) NULL; - v->uv_querier->al_timer = 0; - v->uv_querier->al_genid = 0; - v->uv_querier->al_pv = 0; - v->uv_querier->al_mv = 0; - v->uv_querier->al_old = 0; - v->uv_querier->al_index = 0; - v->uv_querier->al_timerid = 0; - v->uv_querier->al_query = 0; - v->uv_querier->al_flags = 0; - - v->uv_flags &= ~VIFF_QUERIER; + memset(v->uv_querier, 0, sizeof(struct listaddr)); } + v->uv_flags &= ~VIFF_QUERIER; v->uv_querier->al_addr = *src; time(&v->uv_querier->al_ctime); } @@ -243,7 +230,7 @@ accept_listener_query(src, dst, group, tmo) * Reset the timer since we've received a query. */ if (v->uv_querier && inet6_equal(src, &v->uv_querier->al_addr)) - v->uv_querier->al_timer = 0; + v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL; /* * If this is a Group-Specific query which we did not source, we must set @@ -369,7 +356,7 @@ accept_listener_report(src, dst, group) { IF_DEBUG(DEBUG_MLD) log(LOG_DEBUG,0, - "The group don't exist , trying to add it"); + "The group don't exist , trying to add it"); g = (struct listaddr *) malloc(sizeof(struct listaddr)); if (g == NULL) @@ -386,7 +373,7 @@ accept_listener_report(src, dst, group) g->al_next = v->uv_groups; v->uv_groups = g; time(&g->al_ctime); - + add_leaf(mifi, NULL, &group_sa); } } @@ -405,7 +392,7 @@ accept_listener_done(src, dst, group) struct sockaddr_in6 group_sa = {sizeof(group_sa), AF_INET6}; /* Don't create routing entries for the LAN scoped addresses */ - + if (IN6_IS_ADDR_MC_NODELOCAL(group)) /* sanity? */ { IF_DEBUG(DEBUG_MLD) @@ -521,7 +508,7 @@ DelVif(arg) /* increment statistics */ v->uv_listener_timo++; - + anp = &(v->uv_groups); while ((a = *anp) != NULL) { diff --git a/usr.sbin/pim6sd/mld6_proto.h b/usr.sbin/pim6sd/mld6_proto.h index 644eb8d00c5e6..e9cb7ebeb8c18 100644 --- a/usr.sbin/pim6sd/mld6_proto.h +++ b/usr.sbin/pim6sd/mld6_proto.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,25 +32,26 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef MLD6_PROTO_H -#define MLD6_PROTO_H +#define MLD6_PROTO_H #include "vif.h" extern void query_groups __P((struct uvif *v)); -extern int check_grp_membership __P((struct uvif *v, +extern int check_grp_membership __P((struct uvif *v, struct sockaddr_in6 *group)); extern void accept_listener_query __P((struct sockaddr_in6 *src, struct in6_addr *dst, diff --git a/usr.sbin/pim6sd/mrt.c b/usr.sbin/pim6sd/mrt.c index ae21aa3000fe7..02f15dcbae72f 100644 --- a/usr.sbin/pim6sd/mrt.c +++ b/usr.sbin/pim6sd/mrt.c @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,15 +36,16 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #include <syslog.h> @@ -70,7 +69,7 @@ grpentry_t *grplist; * Local functions definition */ static srcentry_t *create_srcentry __P((struct sockaddr_in6 *source)); -static int search_srclist __P((struct sockaddr_in6 *source , +static int search_srclist __P((struct sockaddr_in6 *source , srcentry_t ** sourceEntry)); static int search_srcmrtlink __P((srcentry_t * srcentry_ptr, @@ -705,7 +704,7 @@ search_grplist(group, groupEntry) if (inet6_lessthan(&g->group, group)) continue; - if (inet6_equal(&g->group, group)) + if (inet6_equal(&g->group, group)) { *groupEntry = g; return (TRUE); @@ -741,7 +740,7 @@ create_srcentry(source) * Free the memory if there is error getting the iif and the next hop * (upstream) router. */ - + if (set_incoming(srcentry_ptr, PIM_IIF_SOURCE) == FALSE) { free((char *) srcentry_ptr); @@ -815,7 +814,7 @@ create_grpentry(group) /* * Return TRUE if the entry is found and then *mrtPtr is set to point to that - * entry. Otherwise return FALSE and *mrtPtr points the the previous entry + * entry. Otherwise return FALSE and *mrtPtr points the previous entry * (or NULL if first in the chain. */ static int @@ -835,7 +834,7 @@ search_srcmrtlink(srcentry_ptr, group, mrtPtr) * The entries are ordered with the smaller group address first. The * addresses are in network order. */ - + if (inet6_lessthan(&mrtentry_ptr->group->group, group)) continue; if (inet6_equal(&mrtentry_ptr->group->group, group)) @@ -852,7 +851,7 @@ search_srcmrtlink(srcentry_ptr, group, mrtPtr) /* * Return TRUE if the entry is found and then *mrtPtr is set to point to that - * entry. Otherwise return FALSE and *mrtPtr points the the previous entry + * entry. Otherwise return FALSE and *mrtPtr points the previous entry * (or NULL if first in the chain. */ static int @@ -978,7 +977,7 @@ alloc_mrtentry(srcentry_ptr, grpentry_ptr) mrtentry_ptr->pmbr_addr.sin6_addr = in6addr_any; mrtentry_ptr->pmbr_addr.sin6_len = sizeof(struct sockaddr_in6); mrtentry_ptr->pmbr_addr.sin6_family = AF_INET6; - + #ifdef RSRR mrtentry_ptr->rsrr_cache = (struct rsrr_cache *) NULL; #endif /* RSRR */ @@ -1081,6 +1080,12 @@ create_mrtentry(srcentry_ptr, grpentry_ptr, flags) insert_grpmrtlink(r_new, r_grp_insert, grpentry_ptr); insert_srcmrtlink(r_new, r_src_insert, srcentry_ptr); r_new->flags |= MRTF_SG; + + IF_DEBUG(DEBUG_MFC) + log(LOG_DEBUG, 0, "create SG entry, source %s, group %s", + inet6_fmt(&source->sin6_addr), + inet6_fmt(&group->sin6_addr)); + return (r_new); } diff --git a/usr.sbin/pim6sd/mrt.h b/usr.sbin/pim6sd/mrt.h index dbe31ca13bf7f..4aa428e1647a9 100644 --- a/usr.sbin/pim6sd/mrt.h +++ b/usr.sbin/pim6sd/mrt.h @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,20 +36,21 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef MRT_H -#define MRT_H +#define MRT_H #include <sys/param.h> #include <sys/time.h> @@ -67,31 +66,31 @@ /* flags for the mrt entries */ -#define MRTF_SPT 0x0001 /* iif toward source */ -#define MRTF_WC 0x0002 /* (*,G) entry */ -#define MRTF_RP 0x0004 /* iif toward RP */ -#define MRTF_NEW 0x0008 /* new created routing entry */ -#define MRTF_IIF_REGISTER 0x0020 /* ??? */ -#define MRTF_REGISTER 0x0080 /* ??? */ -#define MRTF_KERNEL_CACHE 0x0200 /* a mirror for the kernel cache */ -#define MRTF_NULL_OIF 0x0400 /* null oif cache.. ??? */ -#define MRTF_REG_SUPP 0x0800 /* register suppress ??? */ -#define MRTF_ASSERTED 0x1000 /* upstream is not that of src ??? */ -#define MRTF_SG 0x2000 /* (S,G) pure, not hanging off of (*,G)*/ -#define MRTF_PMBR 0x4000 /* (*,*,RP) entry (for interop) */ -#define MRTF_MFC_CLONE_SG 0x8000 /* clone (S,G) MFC from (*,G) or (*,*,RP) */ +#define MRTF_SPT 0x0001 /* iif toward source */ +#define MRTF_WC 0x0002 /* (*,G) entry */ +#define MRTF_RP 0x0004 /* iif toward RP */ +#define MRTF_NEW 0x0008 /* new created routing entry */ +#define MRTF_IIF_REGISTER 0x0020 /* ??? */ +#define MRTF_REGISTER 0x0080 /* ??? */ +#define MRTF_KERNEL_CACHE 0x0200 /* a mirror for the kernel cache */ +#define MRTF_NULL_OIF 0x0400 /* null oif cache.. ??? */ +#define MRTF_REG_SUPP 0x0800 /* register suppress ??? */ +#define MRTF_ASSERTED 0x1000 /* upstream is not that of src ??? */ +#define MRTF_SG 0x2000 /* (S,G) pure, not hanging off of (*,G)*/ +#define MRTF_PMBR 0x4000 /* (*,*,RP) entry (for interop) */ +#define MRTF_MFC_CLONE_SG 0x8000 /* clone (S,G) MFC from (*,G) or (*,*,RP) */ -#define CREATE TRUE -#define DONT_CREATE FALSE +#define CREATE TRUE +#define DONT_CREATE FALSE -#define MFC_MOVE_FORCE 0x1 -#define MFC_UPDATE_FORCE 0x2 +#define MFC_MOVE_FORCE 0x1 +#define MFC_UPDATE_FORCE 0x2 /* Macro to duplicate oif info (oif bits, timers) */ -#define VOIF_COPY(from , to ) \ +#define VOIF_COPY(from , to ) \ do { \ IF_COPY(&from->joined_oifs , &to->joined_oifs); \ IF_COPY(&from->oifs ,&to->oifs ); \ @@ -105,7 +104,7 @@ } while (0) -#define FREE_MRTENTRY(mrtentry_ptr) \ +#define FREE_MRTENTRY(mrtentry_ptr) \ do { \ kernel_cache_t *prev; \ kernel_cache_t *next; \ @@ -135,12 +134,12 @@ typedef struct build_jp_message { u_int32 jp_message_size; /* Size of the Join/Prune message (in bytes) */ u_int16 holdtime; /* Join/Prune message holdtime field */ struct sockaddr_in6 curr_group; /* Current group address */ - u_int8 curr_group_msklen; /* Current group masklen */ + u_int8 curr_group_msklen; /* Current group masklen */ u_int8 *join_list; /* The working area for the join addresses */ u_int32 join_list_size; /* The size of the join_list (in bytes) */ u_int16 join_addr_number; /* Number of the join addresses in join_list */ u_int8 *prune_list; /* The working area for the prune addresses */ - u_int32 prune_list_size; /* The size of the prune_list (in bytes) */ + u_int32 prune_list_size; /* The size of the prune_list (in bytes) */ u_int16 prune_addr_number; /* Number of the prune addresses in prune_list*/ u_int8 *rp_list_join; /* The working area for RP join addresses */ u_int32 rp_list_join_size; /* The size of the rp_list_join (in bytes) */ @@ -148,21 +147,21 @@ typedef struct build_jp_message { u_int8 *rp_list_prune; /* The working area for RP prune addresses */ u_int32 rp_list_prune_size; /* The size of the rp_list_prune (in bytes) */ u_int16 rp_list_prune_number; /* Number of RP addresses in rp_list_prune */ - u_int8 *num_groups_ptr; /* Pointer to number_of_groups in jp_message */ + u_int8 *num_groups_ptr; /* Pointer to number_of_groups in jp_message */ } build_jp_message_t; typedef struct pim_nbr_entry { struct pim_nbr_entry *next; /* link to next neighbor */ - struct pim_nbr_entry *prev; /* link to prev neighbor */ + struct pim_nbr_entry *prev; /* link to prev neighbor */ struct sockaddr_in6 address; /* neighbor address */ - vifi_t vifi; /* which interface */ - u_int16 timer; /* for timing out neighbor */ + vifi_t vifi; /* which interface */ + u_int16 timer; /* for timing out neighbor */ build_jp_message_t *build_jp_message; /* A structure for fairly * complicated Join/Prune * message construction. */ - + } pim_nbr_entry_t; typedef struct srcentry { @@ -173,8 +172,8 @@ typedef struct srcentry { vifi_t incoming; /* incoming vif */ struct pim_nbr_entry *upstream; /* upstream router */ u_int32 metric; /* Unicast Routing Metric to the source */ - u_int32 preference; /* The metric preference (for assers)*/ - u_int16 timer; /* Entry timer??? Delete? */ + u_int32 preference; /* The metric preference (for assers)*/ + u_int16 timer; /* Entry timer??? Delete? */ struct cand_rp *cand_rp; /* Used if this is rpentry_t */ } srcentry_t; typedef srcentry_t rpentry_t; @@ -204,13 +203,13 @@ typedef struct rp_grp_entry { struct rp_grp_entry *rp_grp_prev; /* Prev entry for same RP */ struct rp_grp_entry *grp_rp_next; /* Next entry for same grp prefix */ struct rp_grp_entry *grp_rp_prev; /* Prev entry for same grp prefix */ - struct grpentry *grplink; /* Link to all grps via this entry*/ + struct grpentry *grplink; /* Link to all grps via this entry*/ u_int16 advholdtime; /* The advertised holdtime */ u_int16 holdtime; /* The RP holdtime (will be aged) */ u_int16 fragment_tag; /* The fragment tag from the * received BSR message */ - + u_int8 priority; /* The RP priority */ grp_mask_t *group; /* Pointer to (group,mask) entry */ cand_rp_t *rp; /* Pointer to the RP */ @@ -250,7 +249,7 @@ typedef struct mrtentry { u_int32 metric; /* Routing Metric for this entry */ u_int32 preference; /* The metric preference value */ struct sockaddr_in6 pmbr_addr; /* The PMBR address (for interop) */ - u_int16 *vif_timers; /* vifs timer list */ + u_int16 *vif_timers; /* vifs timer list */ u_int16 *vif_deletion_delay; /* vifs deletion delay list */ u_int16 flags; /* The MRTF_* flags */ @@ -277,7 +276,7 @@ typedef struct mrtentry { struct sg_count { u_quad_t pktcnt; /* Number of packets for (s,g) */ u_quad_t bytecnt; /* Number of bytes for (s,g) */ - u_quad_t wrong_if; /* Number of packets received on wrong iif for (s,g) */ + u_quad_t wrong_if; /* Number of packets received on wrong iif for (s,g) */ }; /* @@ -311,17 +310,17 @@ struct vif_count { u_long ocount; /* Output packet count on vif */ u_long ibytes; /* Input byte count on vif */ u_long obytes; /* Output byte count on vif */ -}; +}; /* globals and functions exportations */ extern srcentry_t *srclist; extern grpentry_t *grplist; -extern void init_pim6_mrt __P(()); +extern void init_pim6_mrt __P((void)); extern mrtentry_t *find_route __P((struct sockaddr_in6 *source, struct sockaddr_in6 *group, - u_int16 flags, char create)); + u_int16 flags, char create)); extern grpentry_t *find_group __P((struct sockaddr_in6 *group)); extern srcentry_t *find_source __P((struct sockaddr_in6 *source)); extern void delete_mrtentry __P((mrtentry_t *mrtentry_ptr)); diff --git a/usr.sbin/pim6sd/mtrace6/Makefile b/usr.sbin/pim6sd/mtrace6/Makefile index 2c198b873625c..d59e76fa94aff 100644 --- a/usr.sbin/pim6sd/mtrace6/Makefile +++ b/usr.sbin/pim6sd/mtrace6/Makefile @@ -11,7 +11,7 @@ # 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 @@ -35,15 +35,15 @@ # documentation, and that any documentation, advertising materials, # and other materials related to such distribution and use acknowledge # that the software was developed by the University of Oregon. -# The name of the University of Oregon may not be used to endorse or -# promote products derived from this software without specific prior +# The name of the University of Oregon may not be used to endorse or +# promote products derived from this software without specific prior # written permission. # # THE UNIVERSITY OF OREGON DOES NOT MAKE ANY REPRESENTATIONS # ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND # NON-INFRINGEMENT. # # IN NO EVENT SHALL UO, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -55,17 +55,17 @@ # noted when applicable. # # -# Questions concerning this software should be directed to +# Questions concerning this software should be directed to # Kurt Windisch (kurtw@antc.uoregon.edu) # -# $Id: Makefile,v 1.2 1999/09/13 01:23:22 jinmei Exp $ +# $Id: Makefile,v 1.3 2000/02/25 06:35:42 itojun Exp $ # $FreeBSD$ # # #Part of this program has been derived from PIM sparse-mode pimd. #The pimd program is covered by the license in the accompanying file #named "LICENSE.pimd". -# +# #The pimd program is COPYRIGHT 1998 by University of Southern California. # #Part of this program has been derived from mrouted. @@ -78,9 +78,8 @@ PROG= mtrace6 CFLAGS+=-Wall -CFLAGS+= -I$(.CURDIR)/.. +CFLAGS+= -I$(.CURDIR)/.. -DHAVE_GETIFADDRS MAN8= mtrace6.8 .include <bsd.prog.mk> - diff --git a/usr.sbin/pim6sd/mtrace6/mtrace6.8 b/usr.sbin/pim6sd/mtrace6/mtrace6.8 index ff40022b4dcbd..d6a774106156d 100644 --- a/usr.sbin/pim6sd/mtrace6/mtrace6.8 +++ b/usr.sbin/pim6sd/mtrace6/mtrace6.8 @@ -1,6 +1,6 @@ .\" 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: @@ -12,7 +12,7 @@ .\" 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 @@ -26,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" $Id: mtrace6.8,v 1.3 1999/09/12 17:03:18 jinmei Exp $ -.\" $FreeBSD$ +.\" $FreeBSD$ .\" .Dd Sep 12, 1999 .Dt MTRACE6 8 @@ -50,8 +50,7 @@ a receiver .Sh DESCRIPTION .Nm utilizes a tracing feature implemented in multicast routers that is -accessed via an extension to the MLD protocol. -A trace query is +accessed via an extension to the MLD protocol. A trace query is passed hop-by-hop along the reverse path from the .Ar destination to the @@ -63,7 +62,7 @@ along the path, and then the response is returned to the requestor. .It Fl d Ar destination Specifies the multicast receiver that the query wants to trace. It is the host running -.Nm +.Nm mtrace6 by default. .It Fl g Ar gateway Send the trace query via unicast directly to the multicast router @@ -75,8 +74,7 @@ can also be a multicast address that the last hop router joins. .It Fl h Ar hops Set .Ar hops -to the IPv6 hop limit field of query packets. -The default is 64. +to the IPv6 hop limit field of query packets. The default is 64. .It Fl i Ar interface Specifies the local interface (on a multi-homed host) for sending the trace query and as the default for the receiver and the response @@ -85,8 +83,7 @@ destination. Set to .Ar maxhops to the maximum number of hops that will be traced from the receiver -back toward the source. -The default is 127 hops. +back toward the source. The default is 127 hops. .It Fl n Print hop addresses numerically rather than symbolically and numerically (saves a nameserver address-to-name lookup for each router found on @@ -94,20 +91,18 @@ the path). .It Fl r Ar response_addr Specify the host that the trace response sends to. By default, the response will send to the host running -.Nm Ns . +.Nm mtrace6 . .It Fl w Ar waittime -Set the time to wait for a trace response to +Set the time to wait for a trace response to .Ar waittime -seconds. -The default is 3 seconds. +seconds. The default is 3 seconds. .El .Sh SEE ALSO -.Xr mtrace 8 , .Xr pim6dd 8 , -.Xr pim6sd 8 +.Xr pim6sd 8 , +.Xr mtrace 8 .Sh BUGS -Multicast trace for IPv6 is experimental. -MLD types for query and +Multicast trace for IPv6 is experimental. MLD types for query and response, and packet format are not officially defined. .Pp .Ar waittime @@ -116,7 +111,7 @@ specified by the option is currently meaningless. .Sh HISTORY The -.Nm +.Nm mtrace6 command first appeared in WIDE/KAME IPv6 protocol stack kit. .Pp IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack diff --git a/usr.sbin/pim6sd/mtrace6/mtrace6.c b/usr.sbin/pim6sd/mtrace6/mtrace6.c index f2befc61cab27..b6c838dff4139 100644 --- a/usr.sbin/pim6sd/mtrace6/mtrace6.c +++ b/usr.sbin/pim6sd/mtrace6/mtrace6.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -42,9 +42,8 @@ #include <netinet/in.h> -#include <netinet6/in6.h> #include <netinet6/in6_var.h> -#include <netinet6/icmp6.h> +#include <netinet/icmp6.h> #include <string.h> #include <stdio.h> @@ -52,17 +51,39 @@ #include <stdlib.h> #include <netdb.h> #include <err.h> +#ifdef HAVE_GETIFADDRS +#include <ifaddrs.h> +#endif #include "trace.h" -static void usage(), open_socket(), make_packet(), mtrace_loop(), show_result(); - static char *gateway, *intface, *source, *group, *receiver, *destination; static int mldsoc, hops = 64, maxhops = 127, waittime = 3, querylen, opt_n; -static struct sockaddr *gw_sock, *src_sock, *grp_sock, *dst_sock, *rcv_sock; +static struct sockaddr *gw_sock, *src_sock, *grp_sock, *dst_sock, *rcv_sock; static char *querypacket; static char frombuf[1024]; /* XXX: enough size? */ +int main __P((int, char *[])); +static char *proto_type __P((u_int)); +static char *pr_addr __P((struct sockaddr *, int)); +static void setqid __P((int, char *)); +static void mtrace_loop __P((void)); +static char *str_rflags __P((int)); +static void show_ip6_result __P((struct sockaddr_in6 *, int)); +static void show_result __P((struct sockaddr *, int)); +static void set_sockaddr __P((char *, struct addrinfo *, struct sockaddr *)); +static int is_multicast __P((struct sockaddr *)); +static char *all_routers_str __P((int)); +static int ip6_validaddr __P((char *, struct sockaddr_in6 *)); +static int get_my_sockaddr __P((int, struct sockaddr *)); +static void set_hlim __P((int, struct sockaddr *, int)); +static void set_join __P((int, char *, struct sockaddr *)); +static void set_filter __P((int, int)); +static void open_socket __P((void)); +static void make_ip6_packet __P((void)); +static void make_packet __P((void)); +static void usage __P((void)); + int main(argc, argv) int argc; @@ -126,6 +147,8 @@ main(argc, argv) make_packet(); mtrace_loop(); + exit(0); + /*NOTREACHED*/ } static char * @@ -159,7 +182,7 @@ proto_type(type) static char * pr_addr(addr, numeric) - struct sockaddr_in6 *addr; + struct sockaddr *addr; int numeric; { static char buf[MAXHOSTNAMELEN]; @@ -169,8 +192,7 @@ pr_addr(addr, numeric) flag |= NI_NUMERICHOST; flag |= NI_WITHSCOPEID; - getnameinfo((struct sockaddr *)addr, addr->sin6_len, buf, sizeof(buf), - NULL, 0, flag); + getnameinfo(addr, addr->sa_len, buf, sizeof(buf), NULL, 0, flag); return (buf); } @@ -314,8 +336,8 @@ show_ip6_result(from6, datalen) printf("%3d ", -i);/* index */ /* router address and incoming/outgoing interface */ printf("%s", pr_addr((struct sockaddr *)&sa_resp, opt_n)); - printf("(%s/%ld->%ld) ", - pr_addr((struct sckaddr *)&sa_upstream), + printf("(%s/%d->%d) ", + pr_addr((struct sockaddr *)&sa_upstream, 1), ntohl(rp->tr_inifid), ntohl(rp->tr_outifid)); /* multicast routing protocol type */ printf("%s ", proto_type(rp->tr_rproto)); @@ -394,7 +416,7 @@ all_routers_str(family) } } -int +static int ip6_validaddr(ifname, addr) char *ifname; struct sockaddr_in6 *addr; @@ -426,12 +448,39 @@ ip6_validaddr(ifname, addr) return(1); } -int +static int get_my_sockaddr(family, addrp) int family; struct sockaddr *addrp; { -#define IF_BUFSIZE 8192 /* XXX: adhoc...should be customizable? */ +#ifdef HAVE_GETIFADDRS + struct ifaddrs *ifap, *ifa; + + if (getifaddrs(&ifap) != 0) { + err(1, "getifaddrs"); + /*NOTREACHED */ + } + + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr->sa_family == family) { + switch(family) { + case AF_INET6: + if (ip6_validaddr(ifa->ifa_name, + (struct sockaddr_in6 *)ifa->ifa_addr)) + goto found; + } + } + } + + freeifaddrs(ifap); + return (-1); /* not found */ + + found: + memcpy((void *)addrp, (void *)ifa->ifa_addr, ifa->ifa_addr->sa_len); + freeifaddrs(ifap); + return (0); +#else +#define IF_BUFSIZE 8192 /* XXX: adhoc...should be customizable? */ int i, s; struct ifconf ifconf; struct ifreq *ifrp; @@ -471,7 +520,8 @@ get_my_sockaddr(family, addrp) found: memcpy((void *)addrp, (void *)&ifrp->ifr_addr, ifrp->ifr_addr.sa_len); return(0); -#undef IF_BUFSIZE +#undef IF_BUFSIZE +#endif } static void @@ -504,7 +554,7 @@ set_join(s, ifname, group) { struct ipv6_mreq mreq6; u_int ifindex; - + switch(group->sa_family) { case AF_INET6: if ((ifindex = if_nametoindex(ifname)) == 0) @@ -522,6 +572,7 @@ set_join(s, ifname, group) static void set_filter(s, family) + int s, family; { struct icmp6_filter filter6; @@ -595,7 +646,7 @@ open_socket() #else errx(1, "receive I/F is not specified for multicast" "response(%s)", receiver); -#endif +#endif } } else { @@ -655,7 +706,8 @@ make_packet() static void usage() { - errx(1, + fprintf(stderr, "usage: mtrace6 %s\n", "[-d destination] [-g gateway] [-h hops] [-i interface] " "[-m maxhops] [-n] [-r response_addr] [-w waittime] source group"); + exit(1); } diff --git a/usr.sbin/pim6sd/pathnames.h b/usr.sbin/pim6sd/pathnames.h index 6401b10dd0e4b..27e871a90c4d4 100644 --- a/usr.sbin/pim6sd/pathnames.h +++ b/usr.sbin/pim6sd/pathnames.h @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,12 +36,12 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * @@ -56,13 +54,14 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #ifndef PATHNAMES_H -#define PATHNAMES_H +#define PATHNAMES_H -#define _PATH_PIM6D_CONF "/etc/pim6sd.conf" -#define _PATH_PIM6D_LOGFILE "/var/log/pim6sd.log" +#define _PATH_PIM6D_CONF "/etc/pim6sd.conf" +#define _PATH_PIM6D_LOGFILE "/var/log/pim6sd.log" #if (defined(BSD) && (BSD >= 199103)) #define _PATH_PIM6D_PID "/var/run/pim6sd.pid" diff --git a/usr.sbin/pim6sd/pim6.c b/usr.sbin/pim6sd/pim6.c index 117179d215aea..27416932f95e3 100644 --- a/usr.sbin/pim6sd/pim6.c +++ b/usr.sbin/pim6sd/pim6.c @@ -53,8 +53,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -62,15 +60,16 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #include <sys/param.h> @@ -106,11 +105,13 @@ static struct iovec sndiovpim[2]; static struct iovec rcviovpim[2]; static struct msghdr sndmhpim, rcvmhpim; -static u_char sndcmsgbufpim[CMSG_SPACE(sizeof(struct in6_pktinfo))]; -static u_char rcvcmsgbufpim[CMSG_SPACE(sizeof(struct in6_pktinfo))]; +static u_char *sndcmsgbufpim = NULL; +static int sndcmsglen; +static u_char *rcvcmsgbufpim = NULL; +static int rcvcmsglen; -/* +/* * Local function definitions. */ static void pim6_read __P((int f, fd_set *rfd)); @@ -120,7 +121,8 @@ static int pim6_cksum __P((u_short *, struct in6_addr *, -void init_pim6() +void +init_pim6() { struct cmsghdr *cmsgp; int on; @@ -162,7 +164,7 @@ void init_pim6() if (setsockopt(pim6_socket, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on)) < 0) log(LOG_ERR, errno, "setsockopt(IPV6_PKTINFO)"); -#endif +#endif /* initialize msghdr for receiving packets */ rcviovpim[0].iov_base = (caddr_t) pim6_recv_buf; @@ -171,21 +173,28 @@ void init_pim6() rcvmhpim.msg_namelen = sizeof (from); rcvmhpim.msg_iov = rcviovpim; rcvmhpim.msg_iovlen = 1; + rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)); + if (rcvcmsgbufpim == NULL && + (rcvcmsgbufpim = malloc(rcvcmsglen)) == NULL) + log(LOG_ERR, 0, "malloc failed"); rcvmhpim.msg_control = (caddr_t ) rcvcmsgbufpim; - rcvmhpim.msg_controllen = sizeof (rcvcmsgbufpim); - + rcvmhpim.msg_controllen = rcvcmsglen; sndmhpim.msg_namelen=sizeof(struct sockaddr_in6); sndmhpim.msg_iov=sndiovpim; sndmhpim.msg_iovlen=1; - sndmhpim.msg_control=(caddr_t)sndcmsgbufpim; - sndmhpim.msg_controllen=sizeof(sndcmsgbufpim); + sndcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)); + if (sndcmsgbufpim == NULL && + (sndcmsgbufpim = malloc(sndcmsglen)) == NULL) + log(LOG_ERR, 0, "malloc failed"); + sndmhpim.msg_control = (caddr_t)sndcmsgbufpim; + sndmhpim.msg_controllen = sndcmsglen; cmsgp=(struct cmsghdr *)sndcmsgbufpim; - cmsgp->cmsg_len=CMSG_SPACE(sizeof(struct in6_pktinfo)); - cmsgp->cmsg_level=IPPROTO_IPV6; - cmsgp->cmsg_type=IPV6_PKTINFO; + cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + cmsgp->cmsg_level = IPPROTO_IPV6; + cmsgp->cmsg_type = IPV6_PKTINFO; - if ( register_input_handler(pim6_socket, pim6_read) <0) + if ( register_input_handler(pim6_socket, pim6_read) <0) log(LOG_ERR,0,"Registering pim6 socket"); /* Initialize the building Join/Prune messages working area */ @@ -238,12 +247,12 @@ pim6_read(f, rfd) static void accept_pim6(pimlen) int pimlen; -{ +{ register struct pim *pim; struct sockaddr_in6 dst; struct in6_pktinfo *pi=NULL; struct sockaddr_in6 *src = (struct sockaddr_in6 *)rcvmhpim.msg_name; - struct cmsghdr *cm; + struct cmsghdr *cm; int ifindex=0; /* sanity check */ @@ -273,15 +282,15 @@ accept_pim6(pimlen) else dst.sin6_scope_id = 0; } - } + } if(pi==NULL) log(LOG_ERR,0,"pim6_socket : unable to get destination packet"); if(ifindex==0) log(LOG_ERR,0,"pim6_socket : unable to get ifindex"); - -#define NOSUCHDEF + +#define NOSUCHDEF #ifdef NOSUCHDEF /* TODO: delete. Too noisy */ IF_DEBUG(DEBUG_PIM_DETAIL) { IF_DEBUG(DEBUG_PIM) { @@ -291,10 +300,10 @@ accept_pim6(pimlen) } } #endif /* NOSUCHDEF */ - + /* Check of PIM version is already done in the kernel */ - + /* * TODO: check the dest. is ALL_PIM_ROUTERS (if multicast address) * is it necessary? @@ -306,10 +315,10 @@ accept_pim6(pimlen) receive_pim6_hello(src, (char *)(pim), pimlen); break; case PIM_REGISTER: - receive_pim6_register(src, &dst, (char *)(pim), pimlen); + receive_pim6_register(src, &dst, (char *)(pim), pimlen); break; case PIM_REGISTER_STOP: - receive_pim6_register_stop(src, &dst, (char *)(pim), pimlen); + receive_pim6_register_stop(src, &dst, (char *)(pim), pimlen); break; case PIM_JOIN_PRUNE: receive_pim6_join_prune(src, &dst, (char *)(pim), pimlen); @@ -342,7 +351,7 @@ accept_pim6(pimlen) inet6_fmt(&src->sin6_addr)); break; } -} +} void send_pim6(char *buf, struct sockaddr_in6 *src, @@ -370,7 +379,7 @@ send_pim6(char *buf, struct sockaddr_in6 *src, if(pim->pim_type == PIM_REGISTER) { sendlen = sizeof(struct pim)+sizeof(pim_register_t); - + } pim->pim_cksum = pim6_cksum((u_int16 *)pim, @@ -405,24 +414,26 @@ send_pim6(char *buf, struct sockaddr_in6 *src, } else { - sndmhpim.msg_control=(caddr_t)sndcmsgbufpim; - sndmhpim.msg_controllen=sizeof(sndcmsgbufpim); + sndmhpim.msg_control = (caddr_t)sndcmsgbufpim; + sndmhpim.msg_controllen = sndcmsglen; sndpktinfo->ipi6_ifindex=src->sin6_scope_id; memcpy(&sndpktinfo->ipi6_addr, &src->sin6_addr, sizeof(sndpktinfo->ipi6_addr)); } - if( sendmsg(pim6_socket, &sndmhpim, 0) <0 ) - if (errno == ENETDOWN) - check_vif_state(); - else - log(LOG_WARNING, errno, "sendmsg from %s to %s", - inet6_fmt(&src->sin6_addr), - inet6_fmt(&dst->sin6_addr)); + if (sendmsg(pim6_socket, &sndmhpim, 0) < 0) { + if (errno == ENETDOWN) + check_vif_state(); + else { + log(LOG_WARNING, errno, "sendmsg from %s to %s", + inet6_fmt(&src->sin6_addr), + inet6_fmt(&dst->sin6_addr)); + } + } if(setloop) k_set_loop(pim6_socket, FALSE); - return; + return; } /* ============================== */ @@ -434,37 +445,37 @@ send_pim6(char *buf, struct sockaddr_in6 *src, * code and should be modified for each CPU to be as fast as possible. */ -#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) -#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} - -static union { - u_short phs[4]; +#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) +#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} + +static union { + u_short phs[4]; struct { - u_long ph_len; + u_long ph_len; u_char ph_zero[3]; - u_char ph_nxt; - } ph; + u_char ph_nxt; + } ph; } uph; - -/* + +/* * Our algorithm is simple, using a 32 bit accumulator (sum), we add - * sequential 16 bit words to it, and at the end, fold back all the + * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. - */ + */ int pim6_cksum(u_short *addr, struct in6_addr *src ,struct in6_addr *dst , int len ) -{ +{ register int nleft = len; register u_short *w; register int sum = 0; u_short answer = 0; - + /* * First create IP6 pseudo header and calculate a summary. - */ + */ w = (u_short *)src; uph.ph.ph_len = htonl(len); uph.ph.ph_nxt = IPPROTO_PIM; - + /* IPv6 source address */ sum += w[0]; /* XXX: necessary? */ @@ -483,7 +494,7 @@ int pim6_cksum(u_short *addr, struct in6_addr *src ,struct in6_addr *dst , int l /* Payload length and upper layer identifier */ sum += uph.phs[0]; sum += uph.phs[1]; sum += uph.phs[2]; sum += uph.phs[3]; - + /* * Secondly calculate a summary of the first mbuf excluding offset. */ @@ -492,16 +503,16 @@ int pim6_cksum(u_short *addr, struct in6_addr *src ,struct in6_addr *dst , int l sum += *w++; nleft -= 2; } - + /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } - + /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); -} +} diff --git a/usr.sbin/pim6sd/pim6.h b/usr.sbin/pim6sd/pim6.h index d57bf4b8ac0d8..4b4356a2e0ca7 100644 --- a/usr.sbin/pim6sd/pim6.h +++ b/usr.sbin/pim6sd/pim6.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,20 +32,21 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef PIM6_H -#define PIM6_H +#define PIM6_H #include <sys/param.h> #include <sys/types.h> @@ -61,9 +60,9 @@ extern struct sockaddr_in6 allpim6routers_group; extern char *pim6_send_buf; extern int pim6_socket; -void init_pim6(); +void init_pim6 __P((void)); extern void send_pim6 __P((char *buf, struct sockaddr_in6 *src, - struct sockaddr_in6 *dst, int type, + struct sockaddr_in6 *dst, int type, int datalen)); diff --git a/usr.sbin/pim6sd/pim6_proto.c b/usr.sbin/pim6sd/pim6_proto.c index 9de795e80ecb6..dd65ed1635ec5 100644 --- a/usr.sbin/pim6sd/pim6_proto.c +++ b/usr.sbin/pim6sd/pim6_proto.c @@ -85,8 +85,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -94,15 +92,16 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #include <sys/types.h> @@ -134,11 +133,11 @@ static int parse_pim6_hello __P((char *pktPtr , int datalen , struct sockaddr_in6 *src, u_int16 *holdtime)); -static int send_pim6_register_stop __P((struct sockaddr_in6 *reg_src , struct sockaddr_in6 *reg_dst , +static int send_pim6_register_stop __P((struct sockaddr_in6 *reg_src , struct sockaddr_in6 *reg_dst , struct sockaddr_in6 *inner_source, struct sockaddr_in6 *inner_grp)); -static build_jp_message_t *get_jp6_working_buff __P(()); +static build_jp_message_t *get_jp6_working_buff __P((void)); static void return_jp6_working_buff __P((pim_nbr_entry_t * pim_nbr)); static void pack_jp6_message __P((pim_nbr_entry_t * pim_nbr)); static void send_jp6_message __P((pim_nbr_entry_t * pim_nbr)); @@ -215,9 +214,9 @@ receive_pim6_hello(src, pim_message, datalen) * translate the addresses in host order. */ - if (inet6_lessthan(src, &nbr->address)) + if (inet6_lessthan(src, &nbr->address)) continue; - if (inet6_equal(src, &nbr->address)) + if (inet6_equal(src, &nbr->address)) { /* We already have an entry for this host */ @@ -322,8 +321,6 @@ receive_pim6_hello(src, pim_message, datalen) } } v->uv_flags &= ~VIFF_DR; - v->uv_flags &= ~VIFF_QUERIER; - } } @@ -374,16 +371,13 @@ delete_pim6_nbr(nbr_delete) } else { - if (inet6_greaterthan(&v->uv_linklocal->pa_addr, - &v->uv_pim_neighbors->address)) - + if (inet6_greaterthan(&v->uv_linklocal->pa_addr, + &v->uv_pim_neighbors->address)) /* * The first address is the new potential remote DR address, but * the local address is the winner. */ - v->uv_flags |= VIFF_DR; - v->uv_flags |= VIFF_QUERIER; } /* Update the source entries */ @@ -712,7 +706,7 @@ receive_pim6_register(reg_src, reg_dst, pim_message, datalen) SET_TIMER(mrtentry_ptr->timer, pim_data_timeout); /* restart timer */ if (!(mrtentry_ptr->flags & MRTF_SPT)) - { + { /* The SPT bit is not set */ if (!nullRegisterBit) @@ -902,7 +896,7 @@ send_pim6_register(pkt) char *buf; ip6=(struct ip6_hdr *)pkt; - + group.sin6_addr = ip6->ip6_dst; source.sin6_addr = ip6->ip6_src; @@ -1017,7 +1011,7 @@ send_pim6_null_register(mrtentry_ptr) dest = &mrtentry_ptr->group->rpaddr; reg_source = max_global_address(); - + send_pim6(pim6_send_buf, reg_source , dest, PIM_REGISTER, pktlen); pim6dstat.out_pim6_register++; /* should be counted separately? */ @@ -1091,15 +1085,15 @@ receive_pim6_register_stop(reg_src, reg_dst, pim_message, datalen) inet6_fmt(&encod_unisrc.unicast_addr)); } return FALSE; - } + } - v=&uvifs[mifi]; + v=&uvifs[mifi]; group.sin6_scope_id = inet6_uvif2scopeid(&group, v); source.sin6_scope_id = inet6_uvif2scopeid(&source, v); - + IF_DEBUG(DEBUG_PIM_REGISTER) { @@ -1135,7 +1129,7 @@ receive_pim6_register_stop(reg_src, reg_dst, pim_message, datalen) } /* restart the Register-Suppression timer */ - + SET_TIMER(mrtentry_ptr->rs_timer, (0.5 * pim_register_suppression_timeout) + (RANDOM() % (pim_register_suppression_timeout + 1))); /* Prune the register_vif from the outgoing list */ @@ -1171,7 +1165,7 @@ send_pim6_register_stop(reg_src, reg_dst, inner_grp, inner_src) send_pim6(pim6_send_buf, reg_src , reg_dst , PIM_REGISTER_STOP, data_ptr-(u_int8 *) buf); pim6dstat.out_pim6_register_stop++; - + return (TRUE); } @@ -1217,7 +1211,7 @@ join_or_prune(mrtentry_ptr, upstream_router) { /* I am not the DR for that subnet. */ return (PIM_ACTION_PRUNE); - } + } if (IF_ISSET(mrtentry_ptr->incoming, &mrtentry_ptr->leaves)) /* I am the DR and have local leaves */ return (PIM_ACTION_JOIN); @@ -1288,7 +1282,7 @@ join_or_prune(mrtentry_ptr, upstream_router) } /* TODO: too long, simplify it! */ -#define PIM6_JOIN_PRUNE_MINLEN (4 + PIM6_ENCODE_UNI_ADDR_LEN + 4) +#define PIM6_JOIN_PRUNE_MINLEN (4 + PIM6_ENCODE_UNI_ADDR_LEN + 4) int receive_pim6_join_prune(src, dst, pim_message, datalen) @@ -1440,13 +1434,13 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) GET_HOSTSHORT(num_j_srcs, data_ptr); GET_HOSTSHORT(num_p_srcs, data_ptr); if (encod_group.masklen > (sizeof(struct in6_addr) << 3)) - continue; + continue; MASKLEN_TO_MASK6(encod_group.masklen, g_mask); group.sin6_addr = encod_group.mcast_addr; group.sin6_scope_id = inet6_uvif2scopeid(&group, v); - - if (!IN6_IS_ADDR_MULTICAST(&group.sin6_addr)) - { + + if (!IN6_IS_ADDR_MULTICAST(&group.sin6_addr)) + { data_ptr += (num_j_srcs + num_p_srcs) * sizeof(pim6_encod_src_addr_t); continue; /* Ignore this group and jump to the next */ @@ -1469,7 +1463,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) if (encod_src.masklen > (sizeof(struct in6_addr) << 3)) continue; - + s_flags = encod_src.flags; MASKLEN_TO_MASK6(encod_src.masklen, s_mask); @@ -1523,7 +1517,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) source.sin6_addr = encod_src.src_addr; source.sin6_scope_id = inet6_uvif2scopeid(&source, v); - + if (!inet6_valid_host(&source)) continue; @@ -1794,7 +1788,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) * Join and the ~(S,G) prune are in the same message, ~(S,G) has the * priority. The spec doesn't say it, but I think the same is true for * (*,*,RP) and ~(S,G) prunes. - * + * * The code below do: (1) Check the whole message for (*,*,RP) Joins. (1.1) * If found, clean all pruned_oifs for all (*,G) and all (S,G) for each * RP in the list, but do not update the kernel cache. Then go back to @@ -1809,7 +1803,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) * (kernel). (3.3) After the Prune part is processed, process the Join * part normally (by applying any changes to the kernel) (4) If there * were (*,*,RP) Join/Prune, process them. - * + * * If the Join/Prune list is too long, it may result in long processing * overhead. The idea above is not to place any wrong info in the kernel, * because it may result in short-time existing traffic forwarding on @@ -1823,7 +1817,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) num_groups_tmp = num_groups; data_ptr_start = data_ptr; star_star_rp_found = FALSE; /* Indicating whether we have (*,*,RP) join */ - + IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) log(LOG_DEBUG,0,"Number of groups to process : %d",num_groups_tmp); @@ -1908,13 +1902,13 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) GET_HOSTSHORT(num_p_srcs, data_ptr); group.sin6_addr = encod_group.mcast_addr; group.sin6_scope_id = inet6_uvif2scopeid(&group, v); - + IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) { log(LOG_DEBUG,0,"Group to process : %s",inet6_fmt(&encod_group.mcast_addr)); log(LOG_DEBUG,0,"Number of join : %d",num_j_srcs ); log(LOG_DEBUG,0,"Number of prune : %d",num_p_srcs ); - } + } if (!IN6_IS_ADDR_MULTICAST(&group.sin6_addr)) { @@ -1959,7 +1953,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) GET_ESADDR6(&encod_src, data_ptr); source.sin6_addr=encod_src.src_addr; source.sin6_scope_id = inet6_uvif2scopeid(&source,v); - + if ((encod_src.flags & USADDR_RP_BIT) && (encod_src.flags & USADDR_WC_BIT)) { @@ -1969,7 +1963,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) * pruned_oifs for all (S,G) entries. */ - if(!inet6_equal(&rpentry_ptr->address, &source)) + if(!inet6_equal(&rpentry_ptr->address, &source)) { ignore_group = TRUE; IF_DEBUG(DEBUG_PIM_JOIN_PRUNE) @@ -2002,7 +1996,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) { GET_ESADDR6(&encod_src, data_ptr); source.sin6_addr = encod_src.src_addr; - source.sin6_scope_id = inet6_uvif2scopeid(&source, v); + source.sin6_scope_id = inet6_uvif2scopeid(&source, v); if (!inet6_valid_host(&source)) continue; @@ -2136,7 +2130,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) * not match the local RP-map, then ignore the whole * group, not only this particular (*,G) prune. */ - if (!inet6_equal(&mrtentry_ptr->group->active_rp_grp->rp->rpentry->address, &source )) + if (!inet6_equal(&mrtentry_ptr->group->active_rp_grp->rp->rpentry->address, &source )) continue; /* The RP address doesn't match. */ if (v->uv_flags & VIFF_POINT_TO_POINT) { @@ -2460,7 +2454,7 @@ receive_pim6_join_prune(src, dst, pim_message, datalen) * we have ~(S,G)RPbit Prune entry, we must include any (*,G) or (*,*,RP) * Currently the whole table is scanned. In the future will have all routing * entries linked in a chain with the corresponding upstream pim_nbr_entry. - * + * * If pim_nbr is not NULL, then send to only this particular PIM neighbor, */ int @@ -3404,7 +3398,7 @@ compare_metrics(local_preference, local_metric, local_address, /************************************************************************ * PIM_BOOTSTRAP ************************************************************************/ -#define PIM6_BOOTSTRAP_MINLEN (PIM_MINLEN + PIM6_ENCODE_UNI_ADDR_LEN) +#define PIM6_BOOTSTRAP_MINLEN (PIM_MINLEN + PIM6_ENCODE_UNI_ADDR_LEN) int receive_pim6_bootstrap(src, dst, pim_message, datalen) @@ -3480,7 +3474,7 @@ receive_pim6_bootstrap(src, dst, pim_message, datalen) GET_BYTE(new_bsr_priority, data_ptr); GET_EUADDR6(&new_bsr_uni_addr, data_ptr); - /* + /* * BSR address must be a global unicast address. * [draft-ietf-pim-ipv6-01.txt sec 4.5] */ @@ -3668,7 +3662,7 @@ receive_pim6_bootstrap(src, dst, pim_message, datalen) } max_data_ptr = (u_int8 *) pim_message + datalen; - + /* * TODO: XXX: this 24 is HARDCODING!!! Do a bunch of definitions and make * it stylish! @@ -3696,6 +3690,15 @@ receive_pim6_bootstrap(src, dst, pim_message, datalen) GET_BYTE(curr_frag_rp_count, data_ptr); GET_HOSTSHORT(reserved_short, data_ptr); MASKLEN_TO_MASK6(curr_group_addr.masklen, curr_group_mask); + + if (IN6_IS_ADDR_MC_NODELOCAL(&curr_group_addr.mcast_addr) || + IN6_IS_ADDR_MC_LINKLOCAL(&curr_group_addr.mcast_addr)) { + log(LOG_WARNING, 0, + "receive_pim6_bootstrap: " + "group prefix has a narraw scope: %s (ignored)", + inet6_fmt(&curr_group_addr.mcast_addr)); + continue; + } if (curr_rp_count == 0) { group_.sin6_addr = curr_group_addr.mcast_addr; @@ -3716,7 +3719,7 @@ receive_pim6_bootstrap(src, dst, pim_message, datalen) if (data_ptr + PIM6_ENCODE_UNI_ADDR_LEN + sizeof(u_int32_t) > max_data_ptr) { log(LOG_NOTICE, 0, - "receive_pim6_bootstrap: Bootstrap from %s on %s " + "receive_pim6_bootstrap: Bootstrap from %s on %s " "does not have enough length to contatin RP information", inet6_fmt(&src->sin6_addr), v->uv_name); @@ -3752,7 +3755,7 @@ receive_pim6_bootstrap(src, dst, pim_message, datalen) group_.sin6_len = sizeof(group_); group_.sin6_family = AF_INET6; group_.sin6_scope_id = inet6_uvif2scopeid(&group_,v); - + add_rp_grp_entry(&cand_rp_list, &grp_mask_list, &rpp_, curr_rp_priority, curr_rp_holdtime, &group_, @@ -3772,7 +3775,7 @@ receive_pim6_bootstrap(src, dst, pim_message, datalen) curr_group_addr.mcast_addr.s6_addr[i] & curr_group_mask.s6_addr[i]; } - + for (grp_mask_ptr = segmented_grp_mask_list; grp_mask_ptr != (grp_mask_t *) NULL; grp_mask_ptr = grp_mask_ptr->next) @@ -3783,7 +3786,7 @@ receive_pim6_bootstrap(src, dst, pim_message, datalen) & grp_mask_ptr->group_mask.s6_addr[i]; } - if (inet6_lessthan(&prefix_h2, &prefix_h)) + if (inet6_greaterthan(&prefix_h2, &prefix_h)) continue; else break; @@ -3867,7 +3870,7 @@ receive_pim6_bootstrap(src, dst, pim_message, datalen) } } - + garbage_collect: /* * Garbage collection. Check all group prefixes and if the fragment_tag @@ -3948,7 +3951,7 @@ send_pim6_bootstrap() * length of PIM header + prefix-cnt(1) + priority(1) + holdtime(2) + * encoded unicast RP addr(18) */ -#define PIM6_CAND_RP_ADV_MINLEN (PIM_MINLEN + PIM6_ENCODE_UNI_ADDR_LEN) +#define PIM6_CAND_RP_ADV_MINLEN (PIM_MINLEN + PIM6_ENCODE_UNI_ADDR_LEN) /* * If I am the Bootstrap router, process the advertisement, otherwise ignore @@ -3973,7 +3976,7 @@ receive_pim6_cand_rp_adv(src, dst, pim_message, datalen) pim6dstat.in_pim6_cand_rp++; /* if I am not the bootstrap RP, then do not accept the message */ - if ((cand_bsr_flag != FALSE) && + if ((cand_bsr_flag != FALSE) && !inet6_equal(&curr_bsr_address, &my_bsr_address)) { log(LOG_NOTICE, 0, @@ -4045,7 +4048,7 @@ receive_pim6_cand_rp_adv(src, dst, pim_message, datalen) return(FALSE); } datalen -= PIM6_ENCODE_GRP_ADDR_LEN; - + GET_EGADDR6(&encod_grp_addr, data_ptr); MASKLEN_TO_MASK6(encod_grp_addr.masklen, grp_mask); group_.sin6_addr = encod_grp_addr.mcast_addr; @@ -4114,7 +4117,7 @@ send_pim6_cand_rp_adv() } data_ptr = (u_int8 *) (pim6_send_buf + sizeof(struct pim)); - + bcopy((char *)cand_rp_adv_message.buffer, (char *) data_ptr, cand_rp_adv_message.message_size); diff --git a/usr.sbin/pim6sd/pim6_proto.h b/usr.sbin/pim6sd/pim6_proto.h index a02e3d3af12e9..46fad58478a3c 100644 --- a/usr.sbin/pim6sd/pim6_proto.h +++ b/usr.sbin/pim6sd/pim6_proto.h @@ -29,28 +29,27 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* Questions concerning this software should be directed to * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg. * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef PIM6_PROTO_H -#define PIM6_PROTO_H +#define PIM6_PROTO_H #include "defs.h" #include "vif.h" #include "mrt.h" @@ -75,29 +74,29 @@ extern int receive_pim6_register_stop __P((struct sockaddr_in6 *src, struct soc extern int send_pim6_register __P((char *pkt)); extern int receive_pim6_join_prune __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst, char *pim_message, int datalen)); -extern int join_or_prune __P((mrtentry_t *mrtentry_ptr, +extern int join_or_prune __P((mrtentry_t *mrtentry_ptr, pim_nbr_entry_t *upstream_router)); extern int receive_pim6_assert __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst, char *pim_message, int datalen)); extern int send_pim6_assert __P((struct sockaddr_in6 *source, struct sockaddr_in6 *group, vifi_t vifi, mrtentry_t *mrtentry_ptr)); -extern int send_periodic_pim6_join_prune __P((vifi_t vifi, +extern int send_periodic_pim6_join_prune __P((vifi_t vifi, pim_nbr_entry_t *pim_nbr, u_int16 holdtime)); extern int add_jp_entry __P((pim_nbr_entry_t *pim_nbr, u_int16 holdtime, struct sockaddr_in6 *group, - u_int8 grp_msklen, struct sockaddr_in6 *source, + u_int8 grp_msklen, struct sockaddr_in6 *source, u_int8 src_msklen, - u_int16 addr_flags, + u_int16 addr_flags, u_int8 join_prune)); extern void pack_and_send_jp6_message __P((pim_nbr_entry_t *pim_nbr)); extern int receive_pim6_cand_rp_adv __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst, char *pim_message, int datalen)); extern int receive_pim6_bootstrap __P((struct sockaddr_in6 *src, struct sockaddr_in6 *dst, char *pim_message, int datalen)); -extern int send_pim6_cand_rp_adv __P(()); -extern void send_pim6_bootstrap __P(()); +extern int send_pim6_cand_rp_adv __P((void)); +extern void send_pim6_bootstrap __P((void)); #endif diff --git a/usr.sbin/pim6sd/pim6sd.8 b/usr.sbin/pim6sd/pim6sd.8 index acba4b83c7e4a..251e176d5f718 100644 --- a/usr.sbin/pim6sd/pim6sd.8 +++ b/usr.sbin/pim6sd/pim6sd.8 @@ -1,6 +1,6 @@ .\" 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: @@ -12,7 +12,7 @@ .\" 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 @@ -25,8 +25,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: pim6sd.8,v 1.4 1999/12/16 05:38:06 jinmei Exp $ -.\" $FreeBSD$ +.\" $Id: pim6sd.8,v 1.6 2000/05/18 16:11:46 itojun Exp $ +.\" $FreeBSD$ .\" .Dd June 10, 1999 .Dt PIM6SD 8 @@ -56,8 +56,7 @@ By default, .Pa /etc/pim6sd.conf is used. .It Fl d -Specify debug levels. -If this option is specified without any arguments, +Specify debug levels. If this option is specified without any arguments, all debug messages will be printed out. A subset of the messages to be printed out can be specified as arguments of the option. @@ -72,12 +71,11 @@ Valid debug levels are and .Ic asserts. .It Fl f -Do not become daemon, run in foreground. -This option is for debugging +Do not become daemon, run in foreground. This option is for debugging use. .El .Pp -.Nm Pim6sd +.Nm Pim6sd automatically configures itself to forward on all multicast-capable interfaces, i.e., interfaces that have the IFF_MULTICAST flag set (excluding the "loopback interface"). @@ -99,8 +97,7 @@ signal. The information includes a list of PIM neighbors, .Nm internal multicast routing table, and -BSR and RP related information. -Also, the program dumps its internal +BSR and RP related information. Also, the program dumps its internal statistics to a file when it receives a SIGINFO signal. .Pp When @@ -142,21 +139,21 @@ It is based on IPv4 PIM sparse-mode .Nm pimd developed at University of Southern California, which has also been derived from -.Nm mrouted. +.Nm mrouted . .Nm Mrouted is COPYRIGHT 1989 by The Board of Trustees of Leland Stanford Junior University. -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 .\" .Sh BUGS .Nm Pim6sd does not contain any unicast routing engine, so a unicast routing -daemon needs to run on the system. +daemon needs to run on the system. .Pp The kernel unicast routing table is periodically polled by .Nm in order to follow changes of existing unicast routes. .\" +.Pp +IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack +was initially integrated into +.Fx 4.0 diff --git a/usr.sbin/pim6sd/pim6sd.conf.5 b/usr.sbin/pim6sd/pim6sd.conf.5 index 9df4b71a46cad..aac9fd869bbf9 100644 --- a/usr.sbin/pim6sd/pim6sd.conf.5 +++ b/usr.sbin/pim6sd/pim6sd.conf.5 @@ -1,6 +1,6 @@ .\" 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: @@ -12,7 +12,7 @@ .\" 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 @@ -25,8 +25,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: pim6sd.conf.5,v 1.7 1999/12/03 07:31:45 jinmei Exp $ -.\" $FreeBSD$ +.\" KAME Id: pim6sd.conf.5,v 1.10 2000/07/09 17:28:42 itojun Exp +.\" $FreeBSD$ .\" .Dd Oct 6, 1999 .Dt PIM6SD.CONF 5 @@ -37,7 +37,7 @@ .\" .Sh DESCRIPTION The -.Nm pim6sd +.Nm configuration file consists of a sequence of statements terminated by a semi-colon (`;'), each of which specifies how the daemon treats each interface on the system, specifies some parameters of the PIM @@ -50,7 +50,7 @@ Lines beginning with are comments. .\".Pp .\"Note that -.\".Nm pim6sd +.\".Xr pim6sd 8 .\"works even without the configuration file, although the daemon .\"will warn that there is no configuration file. .\"In such a case, the daemon will automatically set the default value @@ -65,8 +65,7 @@ The following statements can be specified in the configuration file. .Ar option... .Ic ; .Xc -Specify debug messages to be printed out. -Each +Specify debug messages to be printed out. Each .Ar option usually specifies a subset of the messages to be printed. If an @@ -74,8 +73,7 @@ If an begins with .Ic no , it means that the set of the messages that are specified by the option -will not be printed. -For example, +will not be printed. For example, .Ic `all nomld' means that all the messages except MLD related ones will be printed. Valid options are @@ -106,7 +104,7 @@ By default, a hostname is not resolved. .Ic ; .Xc Specifies -.Nm +.Xr pim6sd 8 to ignore the interface even if the interface is multicast-capable. Note that PIM will be activated on all interfaces by default(including the case where there is no configuration file). @@ -127,7 +125,7 @@ assert message on the interface. If another optional parameter .Ic nolistener is specified, -.Nm pim6sd +.Xr pim6sd 8 will not send any MLD packets on the interface. This option is usually meaningless but will be useful when MLD messages are noisy (e.g. when debugging) and there is surely no @@ -139,7 +137,7 @@ listner on the interface. Specifies a default preference value when sending a PIM assert message. Preferences are used by assert elections to determine upstream routers. Currently -.Nm pim6sd +.Xr pim6sd 8 cannot reliably obtain preferences and metrics from the unicast routing protocols, so a default value may be configured. The default preference is 1024. @@ -147,8 +145,7 @@ The default preference is 1024. .It Ic default_source_metric Ar metric; Specifies a default metric value when sending a PIM assert message. It is recommended that preferences be set such that metrics are never -consulted. -However, default metrics may also be set and will default to +consulted. However, default metrics may also be set and will default to 1024. .\" .It Xo @@ -169,8 +166,7 @@ the holdtime will be * .Ar coef . The default values of the period and the coefficient are 30 and 3.5, -respectively. -The default holdtime is 105 seconds as a result. +respectively. The default holdtime is 105 seconds as a result. .\" .It Xo .Ic join_prune_period Ar period Ar coef; @@ -184,8 +180,7 @@ the holdtime will be * .Ar coef . The default values of the period and the coefficient are 60 and 3.5, -respectively. -Consequently, the default holdtime is 210 seconds. +respectively. Consequently, the default holdtime is 210 seconds. .\" .It Xo .Ic data_timeout Ar timer; @@ -234,7 +229,7 @@ All other parameters are optional and will be set automatically. If an .Ar interface is specified, -.Nm pim6sd +.Xr pim6sd 8 will search for a global address on the specified interface and set the address in Candidate RP Advertisements. An optional parameter @@ -261,6 +256,7 @@ specifies a group prefix that the RP will handle. .Op Ar interface .Op Ic time Ar time .Op Ic priority Ar priority +.Op Ic masklen Ar masklen .Ic ; .Xc Specifies to act as a candidate bootstrap router(BSR). @@ -271,7 +267,7 @@ All other parameters are optional and will be set automatically. If an .Ar interface is specified, -.Nm pim6sd +.Xr pim6sd 8 will search for a global address on the specified interface and set the address in Bootstrap messages. An optional parameter @@ -282,6 +278,11 @@ Another optional parameter .Ic priority specifies the priority of the RP. The default value is 0, which means the lowest priority. +Hash mask length can also be specified by the +.Ic masklen +parametr. Its value, +.Ar masklen , +must be no less than 0 and no greater than 128. .\" .It Xo .Ic switch_register_threshold Ic rate Ar rate Ic interval Ar interval; @@ -312,8 +313,8 @@ The default values are 50000 and 20, respectively. # phyint ep0 preference 101; phyint de0 disable; # -#followings are for a candidate Rendezvous Point, which should usually -#be disabled. +# followings are for a candidate Rendezvous Point, which should usually +# be disabled. cand_bootstrap_router; cand_rp; .Ed @@ -321,14 +322,14 @@ cand_rp; .Xr pim6sd 8 .Sh HISTORY The -.Nm pim6sd +.Xr pim6sd 8 command is developed by Mickael Hoerdt at LSIIT Laboratory. It is based on IPv4 PIM sparse-mode .Nm pimd developed at University of Southern California, which has also been derived from -.Nm mrouted. -.Nm Mrouted +.Nm mrouted . +.Nm mrouted is COPYRIGHT 1989 by The Board of Trustees of Leland Stanford Junior University. .Pp diff --git a/usr.sbin/pim6sd/pim6sd.conf.sample b/usr.sbin/pim6sd/pim6sd.conf.sample index 21cf8e4d3fa3f..2aabc6bbeccac 100644 --- a/usr.sbin/pim6sd/pim6sd.conf.sample +++ b/usr.sbin/pim6sd/pim6sd.conf.sample @@ -1,7 +1,7 @@ # $FreeBSD$ # #The timer granularity. -#More this value is small,more pim6sd will be accurate +#More this value is small,more pim6sd will be accurate #default if not specified : 5 #BE SURE to have to same granularity on ALL routers, #otherwise.... @@ -37,7 +37,7 @@ #syntax : 'data_timeout <number>'. # number is the time after which (S,G) state for a silent source will be deleted -# default if not specified : 210 +# default if not specified : 210 #data_timeout 210; @@ -56,22 +56,22 @@ #probe_time 5; #syntax : 'assert_timeout <number>'. -#this is the interval between the last time an Assert is received and the time at wich the +#this is the interval between the last time an Assert is received and the time at wich the #assert is timeout #default if not specified : 180 #assert_timeout 180; #syntax : <cand_rp> <interface> <time> [time] <priority> [priority] -#and time can't be < 10 -#you can just type cand_rp, +#and time can't be < 10 +#you can just type cand_rp, #samples : #cand_rp; #cand_rp de0; #cand_rp ed0 priority 0 time 6; #syntax : <group_prefix> <multicast address>/<prefix length> -#group_prefix ff06::15 +#group_prefix ff06::15 #default if not specified : ff00::/8 #samples: #group_prefix ff1e::15/128; diff --git a/usr.sbin/pim6sd/pim6stat.1 b/usr.sbin/pim6sd/pim6stat.1 index bff89ac2390b9..0ebf13275f1fd 100644 --- a/usr.sbin/pim6sd/pim6stat.1 +++ b/usr.sbin/pim6sd/pim6stat.1 @@ -1,6 +1,6 @@ .\" 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: @@ -12,7 +12,7 @@ .\" 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 @@ -25,8 +25,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: pim6stat.1,v 1.3 1999/12/16 05:38:06 jinmei Exp $ -.\" $FreeBSD$ +.\" $Id: pim6stat.1,v 1.5 2000/05/05 14:57:14 sumikawa Exp $ +.\" $FreeBSD$ .\" .Dd July 28, 1999 .Dt PIM6STAT 1 @@ -36,11 +36,10 @@ .Nd show PIM for IPv6 status .Sh SYNOPSIS .Nm -.Op Fl d -.Op Fl f dumpfile -.Op Fl p pidfile -.Op Fl s -.Op Fl w waitsec +.Op Fl ds +.Op Fl f Ar dumpfile +.Op Fl p Ar pidfile +.Op Fl w Ar waitsec .Sh DESCRIPTION .Nm Pim6stat shows status or statistics of the PIM for IPv6 daemon currently running. diff --git a/usr.sbin/pim6sd/pimd.h b/usr.sbin/pim6sd/pimd.h index 5ad834765b1f4..4ad81a6b71bda 100644 --- a/usr.sbin/pim6sd/pimd.h +++ b/usr.sbin/pim6sd/pimd.h @@ -29,74 +29,73 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* Questions concerning this software should be directed to * Mickael Hoerdt (hoerdt@clarinet.u-strasbg.fr) LSIIT Strasbourg. * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef PIMD_H -#define PIMD_H +#define PIMD_H #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include "defs.h" -#define PIM_PROTOCOL_VERSION 2 +#define PIM_PROTOCOL_VERSION 2 /* PIM protocol timers (in seconds) */ -#define PIM_REGISTER_SUPPRESSION_TIMEOUT 60 -#define PIM_REGISTER_PROBE_TIME 5 /* Used to send NULL_REGISTER */ -#define PIM_DATA_TIMEOUT 210 +#define PIM_REGISTER_SUPPRESSION_TIMEOUT 60 +#define PIM_REGISTER_PROBE_TIME 5 /* Used to send NULL_REGISTER */ +#define PIM_DATA_TIMEOUT 210 -#define PIM_TIMER_HELLO_PERIOD 30 -#define PIM_JOIN_PRUNE_PERIOD 60 +#define PIM_TIMER_HELLO_PERIOD 30 +#define PIM_JOIN_PRUNE_PERIOD 60 -#define PIM_JOIN_PRUNE_HOLDTIME (3.5 * PIM_JOIN_PRUNE_PERIOD) -#define PIM_RANDOM_DELAY_JOIN_TIMEOUT 4.5 +#define PIM_JOIN_PRUNE_HOLDTIME (3.5 * PIM_JOIN_PRUNE_PERIOD) +#define PIM_RANDOM_DELAY_JOIN_TIMEOUT 4.5 -#define PIM_DEFAULT_CAND_RP_ADV_PERIOD 60 -#define PIM_DEFAULT_BOOTSTRAP_PERIOD 60 +#define PIM_DEFAULT_CAND_RP_ADV_PERIOD 60 +#define PIM_DEFAULT_BOOTSTRAP_PERIOD 60 -#define PIM_BOOTSTRAP_TIMEOUT (2.5 * PIM_DEFAULT_BOOTSTRAP_PERIOD + 10) -#define PIM_TIMER_HELLO_HOLDTIME (3.5 * PIM_TIMER_HELLO_PERIOD) -#define PIM_ASSERT_TIMEOUT 180 +#define PIM_BOOTSTRAP_TIMEOUT (2.5 * PIM_DEFAULT_BOOTSTRAP_PERIOD + 10) +#define PIM_TIMER_HELLO_HOLDTIME (3.5 * PIM_TIMER_HELLO_PERIOD) +#define PIM_ASSERT_TIMEOUT 180 /* Misc definitions */ -#define PIM_DEFAULT_CAND_RP_PRIORITY 0 /* 0 is the highest. Don't know +#define PIM_DEFAULT_CAND_RP_PRIORITY 0 /* 0 is the highest. Don't know * why this is the default. * See the PS version (Mar' 97), * pp.22 bottom of the spec. */ -#define PIM_DEFAULT_BSR_PRIORITY 0 /* 0 is the lowest */ -#define RP_DEFAULT_IPV6_HASHMASKLEN 126 /* the default group msklen used +#define PIM_DEFAULT_BSR_PRIORITY 0 /* 0 is the lowest */ +#define RP_DEFAULT_IPV6_HASHMASKLEN 126 /* the default group msklen used * by the hash function to * calculate the group-to-RP * mapping */ -#define SINGLE_SRC_MSK6LEN 128 /* the single source mask length */ -#define SINGLE_GRP_MSK6LEN 128 /* the single group mask length */ +#define SINGLE_SRC_MSK6LEN 128 /* the single source mask length */ +#define SINGLE_GRP_MSK6LEN 128 /* the single group mask length */ -/* TODO: change? */ -#define PIM_GROUP_PREFIX_DEFAULT_MASKLEN 8 /* The default group masklen if +/* TODO: change? */ +#define PIM_GROUP_PREFIX_DEFAULT_MASKLEN 8 /* The default group masklen if * omitted in the config file. */ @@ -109,15 +108,15 @@ /* TODO: XXX: probably no need for two different intervals. */ -#define PIM_DEFAULT_REG_RATE 50000 /* max # of register bits/s */ -#define PIM_DEFAULT_REG_RATE_INTERVAL 20 /* regrate probe interval */ -#define PIM_DEFAULT_DATA_RATE 50000 /* max # of data bits/s */ -#define PIM_DEFAULT_DATA_RATE_INTERVAL 20 /* datarate check interval */ +#define PIM_DEFAULT_REG_RATE 50000 /* max # of register bits/s */ +#define PIM_DEFAULT_REG_RATE_INTERVAL 20 /* regrate probe interval */ +#define PIM_DEFAULT_DATA_RATE 50000 /* max # of data bits/s */ +#define PIM_DEFAULT_DATA_RATE_INTERVAL 20 /* datarate check interval */ -#define DATA_RATE_CHECK_INTERVAL 20 /* Data rate check interval */ -#define REG_RATE_CHECK_INTERVAL 20 /* PIM Reg. rate check interval*/ +#define DATA_RATE_CHECK_INTERVAL 20 /* Data rate check interval */ +#define REG_RATE_CHECK_INTERVAL 20 /* PIM Reg. rate check interval*/ -#define UCAST_ROUTING_CHECK_INTERVAL 20 /* Unfortunately, if the unicast +#define UCAST_ROUTING_CHECK_INTERVAL 20 /* Unfortunately, if the unicast * routing changes, the kernel * or any of the existing * unicast routing daemons @@ -128,37 +127,37 @@ * Sigh. */ -#define DEFAULT_PHY_RATE_LIMIT 0 /* default phyint rate limit */ -#define DEFAULT_REG_RATE_LIMIT 0 /* default register_vif rate limit */ +#define DEFAULT_PHY_RATE_LIMIT 0 /* default phyint rate limit */ +#define DEFAULT_REG_RATE_LIMIT 0 /* default register_vif rate limit */ /************************************************************************** * PIM Encoded-Unicast, Encoded-Group and Encoded-Source Address formats * *************************************************************************/ /* Address families definition */ -#define ADDRF_RESERVED 0 -#define ADDRF_IPv4 1 -#define ADDRF_IPv6 2 -#define ADDRF_NSAP 3 -#define ADDRF_HDLC 4 -#define ADDRF_BBN1822 5 -#define ADDRF_802 6 -#define ADDRF_ETHERNET ADDRF_802 -#define ADDRF_E163 7 -#define ADDRF_E164 8 -#define ADDRF_SMDS ADDRF_E164 -#define ADDRF_ATM ADDRF_E164 -#define ADDRF_F69 9 -#define ADDRF_TELEX ADDRF_F69 -#define ADDRF_X121 10 -#define ADDRF_X25 ADDRF_X121 -#define ADDRF_IPX 11 -#define ADDRF_APPLETALK 12 -#define ADDRF_DECNET_IV 13 -#define ADDRF_BANYAN 14 -#define ADDRF_E164_NSAP 15 +#define ADDRF_RESERVED 0 +#define ADDRF_IPv4 1 +#define ADDRF_IPv6 2 +#define ADDRF_NSAP 3 +#define ADDRF_HDLC 4 +#define ADDRF_BBN1822 5 +#define ADDRF_802 6 +#define ADDRF_ETHERNET ADDRF_802 +#define ADDRF_E163 7 +#define ADDRF_E164 8 +#define ADDRF_SMDS ADDRF_E164 +#define ADDRF_ATM ADDRF_E164 +#define ADDRF_F69 9 +#define ADDRF_TELEX ADDRF_F69 +#define ADDRF_X121 10 +#define ADDRF_X25 ADDRF_X121 +#define ADDRF_IPX 11 +#define ADDRF_APPLETALK 12 +#define ADDRF_DECNET_IV 13 +#define ADDRF_BANYAN 14 +#define ADDRF_E164_NSAP 15 /* Addresses Encoding Type (specific for each Address Family */ -#define ADDRT_IPv6 0 +#define ADDRT_IPv6 0 /* Encoded-Unicast: 18 bytes long */ @@ -169,10 +168,10 @@ typedef struct pim6_encod_uni_addr_ { * misalignment for the unicast * address when placed in the * memory. Must read it byte-by-byte! - */ + */ } pim6_encod_uni_addr_t; /* XXX: sizeof(pim6_encod_uni_addr_t) does not work due to misalignment */ -#define PIM6_ENCODE_UNI_ADDR_LEN 18 +#define PIM6_ENCODE_UNI_ADDR_LEN 18 /* Encoded-Group */ typedef struct pim6_encod_grp_addr_ { @@ -183,7 +182,7 @@ typedef struct pim6_encod_grp_addr_ { struct in6_addr mcast_addr; } pim6_encod_grp_addr_t; /* XXX: sizeof(pim6_encod_grp_addr_t) MAY NOT work due to an alignment problem */ -#define PIM6_ENCODE_GRP_ADDR_LEN 20 +#define PIM6_ENCODE_GRP_ADDR_LEN 20 /* Encoded-Source */ typedef struct pim6_encod_src_addr_ { @@ -194,11 +193,11 @@ typedef struct pim6_encod_src_addr_ { struct in6_addr src_addr; } pim6_encod_src_addr_t; /* XXX: sizeof(pim6_encod_src_addr_t) MAY NOT work due to an alignment problem */ -#define PIM6_ENCODE_SRC_ADDR_LEN 20 +#define PIM6_ENCODE_SRC_ADDR_LEN 20 -#define USADDR_RP_BIT 0x1 -#define USADDR_WC_BIT 0x2 -#define USADDR_S_BIT 0x4 +#define USADDR_RP_BIT 0x1 +#define USADDR_WC_BIT 0x2 +#define USADDR_S_BIT 0x4 /************************************************************************** * PIM Messages formats * @@ -237,49 +236,49 @@ typedef struct pim_jp_encod_grp_ { } pim_jp_encod_grp_t; -#define PIM_ACTION_NOTHING 0 -#define PIM_ACTION_JOIN 1 -#define PIM_ACTION_PRUNE 2 +#define PIM_ACTION_NOTHING 0 +#define PIM_ACTION_JOIN 1 +#define PIM_ACTION_PRUNE 2 -#define PIM_IIF_SOURCE 1 -#define PIM_IIF_RP 2 +#define PIM_IIF_SOURCE 1 +#define PIM_IIF_RP 2 -#define PIM_ASSERT_RPT_BIT 0x80000000 +#define PIM_ASSERT_RPT_BIT 0x80000000 /* PIM messages type */ -#define PIM_HELLO 0 -#define PIM_REGISTER_STOP 2 -#define PIM_JOIN_PRUNE 3 -#define PIM_BOOTSTRAP 4 -#define PIM_ASSERT 5 -#define PIM_GRAFT 6 -#define PIM_GRAFT_ACK 7 -#define PIM_CAND_RP_ADV 8 +#define PIM_HELLO 0 +#define PIM_REGISTER_STOP 2 +#define PIM_JOIN_PRUNE 3 +#define PIM_BOOTSTRAP 4 +#define PIM_ASSERT 5 +#define PIM_GRAFT 6 +#define PIM_GRAFT_ACK 7 +#define PIM_CAND_RP_ADV 8 -#define PIM_V2_HELLO PIM_HELLO -#define PIM_V2_REGISTER PIM_REGISTER -#define PIM_V2_REGISTER_STOP PIM_REGISTER_STOP -#define PIM_V2_JOIN_PRUNE PIM_JOIN_PRUNE -#define PIM_V2_BOOTSTRAP PIM_BOOTSTRAP -#define PIM_V2_ASSERT PIM_ASSERT -#define PIM_V2_GRAFT PIM_GRAFT -#define PIM_V2_GRAFT_ACK PIM_GRAFT_ACK -#define PIM_V2_CAND_RP_ADV PIM_CAND_RP_ADV +#define PIM_V2_HELLO PIM_HELLO +#define PIM_V2_REGISTER PIM_REGISTER +#define PIM_V2_REGISTER_STOP PIM_REGISTER_STOP +#define PIM_V2_JOIN_PRUNE PIM_JOIN_PRUNE +#define PIM_V2_BOOTSTRAP PIM_BOOTSTRAP +#define PIM_V2_ASSERT PIM_ASSERT +#define PIM_V2_GRAFT PIM_GRAFT +#define PIM_V2_GRAFT_ACK PIM_GRAFT_ACK +#define PIM_V2_CAND_RP_ADV PIM_CAND_RP_ADV /* Vartious options from PIM messages definitions */ /* PIM_HELLO definitions */ -#define PIM_MESSAGE_HELLO_HOLDTIME 1 -#define PIM_MESSAGE_HELLO_HOLDTIME_LENGTH 2 -#define PIM_MESSAGE_HELLO_HOLDTIME_FOREVER 0xffff +#define PIM_MESSAGE_HELLO_HOLDTIME 1 +#define PIM_MESSAGE_HELLO_HOLDTIME_LENGTH 2 +#define PIM_MESSAGE_HELLO_HOLDTIME_FOREVER 0xffff /* PIM_REGISTER definitions */ -#define PIM_MESSAGE_REGISTER_BORDER_BIT 0x80000000 -#define PIM_MESSAGE_REGISTER_NULL_REGISTER_BIT 0x40000000 +#define PIM_MESSAGE_REGISTER_BORDER_BIT 0x80000000 +#define PIM_MESSAGE_REGISTER_NULL_REGISTER_BIT 0x40000000 -#define MASK_TO_MASKLEN6(mask , masklen) \ +#define MASK_TO_MASKLEN6(mask , masklen) \ do { \ register u_int32 tmp_mask; \ register u_int8 tmp_masklen = sizeof((mask)) <<3; \ @@ -293,9 +292,9 @@ do { \ break; \ } \ (masklen) =tmp_masklen; \ - } while (0) + } while (0) -#define MASKLEN_TO_MASK6(masklen, mask6) \ +#define MASKLEN_TO_MASK6(masklen, mask6) \ do {\ u_char maskarray[8] = \ {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; \ @@ -325,10 +324,10 @@ do { \ * The same for all {PUT,GET}_{NET,HOST}{SHORT,LONG} */ -#define GET_BYTE(val, cp) ((val) = *(cp)++) -#define PUT_BYTE(val, cp) (*(cp)++ = (u_int8)(val)) +#define GET_BYTE(val, cp) ((val) = *(cp)++) +#define PUT_BYTE(val, cp) (*(cp)++ = (u_int8)(val)) -#define GET_HOSTSHORT(val, cp) \ +#define GET_HOSTSHORT(val, cp) \ do { \ register u_int16 Xv; \ Xv = (*(cp)++) << 8; \ @@ -336,7 +335,7 @@ do { \ (val) = Xv; \ } while (0) -#define PUT_HOSTSHORT(val, cp) \ +#define PUT_HOSTSHORT(val, cp) \ do { \ register u_int16 Xv; \ Xv = (u_int16)(val); \ @@ -345,14 +344,14 @@ do { \ } while (0) #if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN) -#define GET_NETSHORT(val, cp) \ +#define GET_NETSHORT(val, cp) \ do { \ register u_int16 Xv; \ Xv = *(cp)++; \ Xv |= (*(cp)++) << 8; \ (val) = Xv; \ } while (0) -#define PUT_NETSHORT(val, cp) \ +#define PUT_NETSHORT(val, cp) \ do { \ register u_int16 Xv; \ Xv = (u_int16)(val); \ @@ -360,11 +359,11 @@ do { \ *(cp)++ = (u_int8)(Xv >> 8); \ } while (0) #else -#define GET_NETSHORT(val, cp) GET_HOSTSHORT(val, cp) -#define PUT_NETSHORT(val, cp) PUT_HOSTSHORT(val, cp) +#define GET_NETSHORT(val, cp) GET_HOSTSHORT(val, cp) +#define PUT_NETSHORT(val, cp) PUT_HOSTSHORT(val, cp) #endif /* {GET,PUT}_NETSHORT */ -#define GET_HOSTLONG(val, cp) \ +#define GET_HOSTLONG(val, cp) \ do { \ register u_long Xv; \ Xv = (*(cp)++) << 24; \ @@ -374,7 +373,7 @@ do { \ (val) = Xv; \ } while (0) -#define PUT_HOSTLONG(val, cp) \ +#define PUT_HOSTLONG(val, cp) \ do { \ register u_int32 Xv; \ Xv = (u_int32)(val); \ @@ -385,7 +384,7 @@ do { \ } while (0) #if defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN) -#define GET_NETLONG(val, cp) \ +#define GET_NETLONG(val, cp) \ do { \ register u_long Xv; \ Xv = *(cp)++; \ @@ -395,7 +394,7 @@ do { \ (val) = Xv; \ } while (0) -#define PUT_NETLONG(val, cp) \ +#define PUT_NETLONG(val, cp) \ do { \ register u_int32 Xv; \ Xv = (u_int32)(val); \ @@ -405,11 +404,11 @@ do { \ *(cp)++ = (u_int8)(Xv >> 24); \ } while (0) #else -#define GET_NETLONG(val, cp) GET_HOSTLONG(val, cp) -#define PUT_NETLONG(val, cp) PUT_HOSTLONG(val, cp) +#define GET_NETLONG(val, cp) GET_HOSTLONG(val, cp) +#define PUT_NETLONG(val, cp) PUT_HOSTLONG(val, cp) #endif /* {GET,PUT}_HOSTLONG */ -#define GET_ESADDR6(esa, cp) /* XXX: hard coding */ \ +#define GET_ESADDR6(esa, cp) /* XXX: hard coding */ \ do { \ (esa)->addr_family = *(cp)++; \ (esa)->encod_type = *(cp)++; \ @@ -419,7 +418,7 @@ do { \ (cp) += sizeof(struct in6_addr); \ } while(0) -#define PUT_ESADDR6(addr, masklen, flags, cp) \ +#define PUT_ESADDR6(addr, masklen, flags, cp) \ do { \ int i; \ struct in6_addr maskaddr; \ @@ -432,7 +431,7 @@ do { \ *(cp) = maskaddr.s6_addr[i] & (addr).s6_addr[i]; \ } while(0) -#define GET_EGADDR6(ega, cp) /* XXX: hard coding */ \ +#define GET_EGADDR6(ega, cp) /* XXX: hard coding */ \ do { \ (ega)->addr_family = *(cp)++; \ (ega)->encod_type = *(cp)++; \ @@ -442,7 +441,7 @@ do { \ (cp) += sizeof(struct in6_addr); \ } while(0) -#define PUT_EGADDR6(addr, masklen, reserved, cp) \ +#define PUT_EGADDR6(addr, masklen, reserved, cp) \ do { \ int i; \ struct in6_addr maskaddr; \ @@ -456,7 +455,7 @@ do { \ } while(0) -#define GET_EUADDR6(eua, cp) /* XXX hard conding */ \ +#define GET_EUADDR6(eua, cp) /* XXX hard conding */ \ do { \ (eua)->addr_family = *(cp)++; \ (eua)->encod_type = *(cp)++; \ @@ -464,7 +463,7 @@ do { \ (cp) += sizeof(struct in6_addr); \ } while(0) -#define PUT_EUADDR6(addr, cp) \ +#define PUT_EUADDR6(addr, cp) \ do { \ *(cp)++ = ADDRF_IPv6; /* family */ \ *(cp)++ = ADDRT_IPv6; /* type */ \ @@ -473,28 +472,28 @@ do { \ } while(0) /* Used if no relaible unicast routing information available */ -#define UCAST_DEFAULT_SOURCE_METRIC 1024 -#define UCAST_DEFAULT_SOURCE_PREFERENCE 1024 +#define UCAST_DEFAULT_SOURCE_METRIC 1024 +#define UCAST_DEFAULT_SOURCE_PREFERENCE 1024 -#define DEFAULT_LOCAL_PREF 101 /* assert pref par defaut */ -#define DEFAULT_LOCAL_METRIC 1024 /* assert metrique par default */ +#define DEFAULT_LOCAL_PREF 101 /* assert pref par defaut */ +#define DEFAULT_LOCAL_METRIC 1024 /* assert metrique par default */ -/* +/* * TODO: recalculate the messages sizes, probably with regard to the MTU * TODO: cleanup */ -#define MAX_JP_MESSAGE_SIZE 8192 -#define MAX_JP_MESSAGE_POOL_NUMBER 8 -#define MAX_JOIN_LIST_SIZE 1500 -#define MAX_PRUNE_LIST_SIZE 1500 +#define MAX_JP_MESSAGE_SIZE 8192 +#define MAX_JP_MESSAGE_POOL_NUMBER 8 +#define MAX_JOIN_LIST_SIZE 1500 +#define MAX_PRUNE_LIST_SIZE 1500 -#define STAR_STAR_RP_MSK6LEN 8 /* Masklen for +#define STAR_STAR_RP_MSK6LEN 8 /* Masklen for * ff00 :: * to encode (*,*,RP) - */ + */ /* interface independent statistics */ struct pim6dstat { diff --git a/usr.sbin/pim6sd/route.c b/usr.sbin/pim6sd/route.c index c455a584399c4..26869f81327ae 100644 --- a/usr.sbin/pim6sd/route.c +++ b/usr.sbin/pim6sd/route.c @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,15 +36,16 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #include <sys/types.h> @@ -207,13 +206,13 @@ set_incoming(srcentry_ptr, srctype) /* * The upstream router must be a (PIM router) neighbor, otherwise we are - * in big trouble ;-). + * in big trouble ;-). * Yes but the neighbors are link-local and the rp is global ipv6.. */ /* WARNING WARNING WARNING WARNING */ /* If the router is directly connected to the RP and the RP is the BSR , the next hop is * the globally reachable addresse of the RP : NOT link local neighbor but - * a ipv6 global neighbor... + * a ipv6 global neighbor... * the upstream router is the globally reachable router... * */ @@ -846,7 +845,7 @@ delete_vif_from_mrt(vifi) } -void +void process_kernel_call() { register struct mrt6msg *im; /* igmpmsg control struct */ @@ -993,7 +992,7 @@ process_cache_miss(im) else rp_addr = mrtentry_ptr->group->rpaddr; mfc_source = source; -// TODO +// TODO #ifdef KERNEL_MFC_WC_G if (mrtentry_ptr->flags & (MRTF_WC | MRTF_PMBR)) if (!(mrtentry_ptr->flags & MRTF_MFC_CLONE_SG)) diff --git a/usr.sbin/pim6sd/route.h b/usr.sbin/pim6sd/route.h index 2adb1fe96f3c3..9dacf1b10e8b1 100644 --- a/usr.sbin/pim6sd/route.h +++ b/usr.sbin/pim6sd/route.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,20 +32,21 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef ROUTE_H -#define ROUTE_H +#define ROUTE_H #include "mrt.h" @@ -58,7 +57,7 @@ int change_interfaces( mrtentry_t *mrtentry_ptr,vifi_t new_iif, if_set *new_joined_oifs,if_set *new_pruned_oifs,if_set *new_leaves_ , if_set *asserted , u_int16 flags); -extern void process_kernel_call __P(()); +extern void process_kernel_call __P((void)); extern int set_incoming __P((srcentry_t *srcentry_ptr, int srctype)); extern vifi_t get_iif __P((struct sockaddr_in6 *source)); @@ -68,7 +67,7 @@ extern int add_sg_oif __P((mrtentry_t *mrtentry_ptr, int update_holdtime)); extern void add_leaf __P((vifi_t vifi, struct sockaddr_in6 *source, struct sockaddr_in6 *group)); -extern void delete_leaf __P((vifi_t vifi, struct sockaddr_in6 *source, +extern void delete_leaf __P((vifi_t vifi, struct sockaddr_in6 *source, struct sockaddr_in6 *group)); @@ -77,7 +76,7 @@ extern void delete_leaf __P((vifi_t vifi, struct sockaddr_in6 *source, extern pim_nbr_entry_t *find_pim6_nbr __P((struct sockaddr_in6 *source)); extern void calc_oifs __P((mrtentry_t *mrtentry_ptr, if_set *oifs_ptr)); -extern void process_kernel_call __P(()); +extern void process_kernel_call __P((void)); extern int delete_vif_from_mrt __P((vifi_t vifi)); extern mrtentry_t *switch_shortest_path __P((struct sockaddr_in6 *source, struct sockaddr_in6 *group)); diff --git a/usr.sbin/pim6sd/routesock.c b/usr.sbin/pim6sd/routesock.c index aced736deef12..04fe94859ad0c 100644 --- a/usr.sbin/pim6sd/routesock.c +++ b/usr.sbin/pim6sd/routesock.c @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,12 +36,12 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * @@ -56,6 +54,7 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #include <sys/param.h> @@ -78,6 +77,7 @@ #include <syslog.h> #include "vif.h" #include "debug.h" +#include "routesock.h" #ifdef HAVE_ROUTING_SOCKETS union sockunion @@ -96,7 +96,7 @@ u_long rtm_inits; /* * Local functions definitions. */ -static int getmsg +static int getmsg __P((register struct rt_msghdr *, int, struct rpfctl * rpfinfo)); @@ -104,17 +104,17 @@ __P((register struct rt_msghdr *, int, * TODO: check again! */ #ifdef IRIX -#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \ +#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \ : sizeof(__uint64_t)) #else -#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ +#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ : sizeof(long)) #endif /* IRIX */ #ifdef HAVE_SA_LEN -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) #else -#define ADVANCE(x, n) (x += ROUNDUP(4)) /* TODO: a hack!! */ +#define ADVANCE(x, n) (x += ROUNDUP(4)) /* TODO: a hack!! */ #endif /* Open and initialize the routing socket */ @@ -175,12 +175,12 @@ k_req_incoming(source, rpfp) /* TODO: a hack!!!! */ #ifdef HAVE_SA_LEN -#define NEXTADDR(w, u) \ +#define NEXTADDR(w, u) \ if (rtm_addrs & (w)) { \ l = ROUNDUP(u.sa.sa_len); bcopy((char *)&(u), cp, l); cp += l;\ } #else -#define NEXTADDR(w, u) \ +#define NEXTADDR(w, u) \ if (rtm_addrs & (w)) { \ l = ROUNDUP(4); bcopy((char *)&(u), cp, l); cp += l;\ } @@ -221,7 +221,7 @@ k_req_incoming(source, rpfp) errno = 0; bzero((char *) &m_rtmsg, sizeof(m_rtmsg)); -#define rtm m_rtmsg.m_rtm +#define rtm m_rtmsg.m_rtm rtm.rtm_type = RTM_GET; rtm.rtm_flags = flags; rtm.rtm_version = RTM_VERSION; @@ -281,7 +281,7 @@ getmsg(rtm, msglen, rpfinfop) struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL; - + struct sockaddr_dl *ifp = NULL; register struct sockaddr *sa; register char *cp; diff --git a/usr.sbin/pim6sd/routesock.h b/usr.sbin/pim6sd/routesock.h index 0d3f9f72f02ea..48f3efc37c4cc 100644 --- a/usr.sbin/pim6sd/routesock.h +++ b/usr.sbin/pim6sd/routesock.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,24 +32,25 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef ROUTESOCK_H -#define ROUTESOCK_H +#define ROUTESOCK_H -void init_routesock(); +int init_routesock __P((void)); extern int pid; extern int k_req_incoming __P((struct sockaddr_in6 *source, - struct rpfctl *rpfp)); + struct rpfctl *rpfp)); #endif diff --git a/usr.sbin/pim6sd/rp.c b/usr.sbin/pim6sd/rp.c index 48936e4bde7c8..e24b71b2f63aa 100644 --- a/usr.sbin/pim6sd/rp.c +++ b/usr.sbin/pim6sd/rp.c @@ -47,7 +47,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -57,8 +57,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -66,15 +64,16 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #include <stdlib.h> @@ -95,10 +94,10 @@ * compatibility ;) */ -#define SEED1 1103515245 -#define SEED2 12345 -#define RP_HASH_VALUE(G, M, C) (((SEED1) * (((SEED1) * ((G) & (M)) + (SEED2)) ^ (C)) + (SEED2)) % 0x80000000) -#define RP_HASH_VALUE2(P, C) (((SEED1) * (((SEED1) * (P) + (SEED2)) ^ (C)) + (SEED2)) % 0x80000000) +#define SEED1 1103515245 +#define SEED2 12345 +#define RP_HASH_VALUE(G, M, C) (((SEED1) * (((SEED1) * ((G) & (M)) + (SEED2)) ^ (C)) + (SEED2)) % 0x80000000) +#define RP_HASH_VALUE2(P, C) (((SEED1) * (((SEED1) * (P) + (SEED2)) ^ (C)) + (SEED2)) % 0x80000000) cand_rp_t *cand_rp_list; grp_mask_t *grp_mask_list; @@ -120,7 +119,7 @@ u_int8 my_cand_rp_priority; u_int16 my_cand_rp_holdtime; u_int16 my_cand_rp_adv_period; /* The locally configured Cand-RP * adv. period. */ -u_int16 my_bsr_period; /* The locally configured BSR +u_int16 my_bsr_period; /* The locally configured BSR period */ u_int16 pim_cand_rp_adv_timer; u_int8 cand_rp_flag = FALSE; /* Candidate RP flag */ @@ -204,9 +203,9 @@ bootstrap_initial_delay() /* * The bootstrap timer initial value (if Cand-BSR). It depends of the * bootstrap router priority: higher priority has shorter value: - * + * * Delay = 5 + 2*log_2(1 + bestPriority - myPriority) + AddrDelay; - * + * * bestPriority = Max(storedPriority, myPriority); if (bestPriority == * myPriority) AddrDelay = log_2(bestAddr - myAddr)/16; else AddrDelay = * 2 - (myAddr/2^31); @@ -241,8 +240,8 @@ bootstrap_initial_delay() */ /* Calculate log_2(Delay) */ // log_mask = sizeof(Delay) << 3; -// log_mask = (1 << (log_mask - 1)); -/* Set the leftmost bit to `1` +// log_mask = (1 << (log_mask - 1)); +/* Set the leftmost bit to `1` */ /* for (log_of_2 = (sizeof(Delay) << 3) - 1; log_of_2; log_of_2--) @@ -360,7 +359,7 @@ add_grp_mask(used_grp_mask_list, group_addr, group_mask, hash_mask) prefix_h.sin6_addr.s6_addr[i] = group_addr->sin6_addr.s6_addr[i] & group_mask.s6_addr[i]; - /* The ordering is: smaller first */ + /* The ordering is: bigger first */ for (grp_mask = *used_grp_mask_list; grp_mask != (grp_mask_t *) NULL; grp_mask_prev = grp_mask, grp_mask = grp_mask->next) { @@ -368,7 +367,7 @@ add_grp_mask(used_grp_mask_list, group_addr, group_mask, hash_mask) prefix_h2.sin6_addr.s6_addr[i] = (grp_mask->group_addr.sin6_addr.s6_addr[i] & grp_mask->group_mask.s6_addr[i]); - if (inet6_lessthan(&prefix_h2, &prefix_h) ) + if (inet6_greaterthan(&prefix_h2, &prefix_h) ) continue; if (inet6_equal(&prefix_h2, &prefix_h)) return (grp_mask); @@ -721,14 +720,14 @@ delete_grp_mask(used_cand_rp_list, used_grp_mask_list, group_addr, group_mask) grp_mask_ptr = grp_mask_ptr->next) { for (i = 0; i < sizeof(struct in6_addr); i++) - prefix_h2.sin6_addr.s6_addr[i] = + prefix_h2.sin6_addr.s6_addr[i] = grp_mask_ptr->group_addr.sin6_addr.s6_addr[i]&grp_mask_ptr->group_mask.s6_addr[i]; - if (inet6_lessthan(&prefix_h2, &prefix_h)) + if (inet6_greaterthan(&prefix_h2, &prefix_h)) continue; if (IN6_ARE_ADDR_EQUAL(&grp_mask_ptr->group_addr.sin6_addr, &group_addr->sin6_addr) && - IN6_ARE_ADDR_EQUAL(&grp_mask_ptr->group_mask, &group_mask)) + IN6_ARE_ADDR_EQUAL(&grp_mask_ptr->group_mask, &group_mask)) break; else return; /* Not found */ @@ -1017,31 +1016,29 @@ rp_grp_match(group) struct sockaddr_in6 prefix_h; struct sockaddr_in6 prefix_h2; - int i; + int i; if (grp_mask_list == (grp_mask_t *) NULL) return (rp_grp_entry_t *) NULL; - - /* XXX :I compare on the adresses , inet6_equal use the scope too */ + + /* XXX: I compare on the adresses, inet6_equal use the scope too */ prefix_h.sin6_scope_id = prefix_h2.sin6_scope_id = 0; for (grp_mask_ptr = grp_mask_list; grp_mask_ptr != (grp_mask_t *) NULL; grp_mask_ptr = grp_mask_ptr->next) { for (i = 0; i < sizeof(struct in6_addr); i++) - prefix_h2.sin6_addr.s6_addr[i] = + prefix_h2.sin6_addr.s6_addr[i] = (grp_mask_ptr->group_addr.sin6_addr.s6_addr[i] & grp_mask_ptr->group_mask.s6_addr[i]); for (i = 0; i < sizeof(struct in6_addr); i++) - prefix_h.sin6_addr.s6_addr[i] = + prefix_h.sin6_addr.s6_addr[i] = (group->sin6_addr.s6_addr[i] & grp_mask_ptr->group_mask.s6_addr[i]); /* Search the grp_mask (group_prefix) list */ - if ((inet6_greaterthan(&prefix_h, &prefix_h2))) + if (!inet6_equal(&prefix_h, &prefix_h2)) continue; - if ((inet6_lessthan(&prefix_h, &prefix_h2))) - break; for (grp_rp_entry_ptr = grp_mask_ptr->grp_rp_next; grp_rp_entry_ptr != (rp_grp_entry_t *) NULL; @@ -1190,7 +1187,7 @@ create_pim6_bootstrap_message(send_buff) * mrtentry_ptr. Return TRUE or FALSE. */ -int +int check_mrtentry_rp(mrtentry_ptr, rp_addr) mrtentry_t *mrtentry_ptr; struct sockaddr_in6 *rp_addr; diff --git a/usr.sbin/pim6sd/rp.h b/usr.sbin/pim6sd/rp.h index 56817f1675d21..a45bc1ccfcc68 100644 --- a/usr.sbin/pim6sd/rp.h +++ b/usr.sbin/pim6sd/rp.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,20 +32,21 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef RP_H -#define RP_H +#define RP_H #include "defs.h" #include "mrt.h" @@ -55,7 +54,7 @@ extern cand_rp_t *cand_rp_list; extern grp_mask_t *grp_mask_list; extern cand_rp_t *segmented_cand_rp_list; -extern grp_mask_t *segmented_grp_mask_list; +extern grp_mask_t *segmented_grp_mask_list; extern u_int8 cand_rp_flag; extern u_int8 cand_bsr_flag; @@ -82,9 +81,9 @@ extern struct cand_rp_adv_message_ { } cand_rp_adv_message; -extern void init_rp6_and_bsr6 __P(()); +extern void init_rp6_and_bsr6 __P((void)); void delete_rp_list( cand_rp_t **used_cand_rp_list , grp_mask_t **used_grp_mask_list ); -u_int16 bootstrap_initial_delay(); +u_int16 bootstrap_initial_delay __P((void)); extern rpentry_t *rp_match __P((struct sockaddr_in6 *group)); extern rp_grp_entry_t *rp_grp_match __P((struct sockaddr_in6 *group)); extern int create_pim6_bootstrap_message __P((char *send_buff)); @@ -101,8 +100,8 @@ extern rp_grp_entry_t *add_rp_grp_entry __P((cand_rp_t **used_cand_rp_list, extern void delete_rp_grp_entry __P((cand_rp_t **used_cand_rp_list, grp_mask_t **used_grp_mask_list, rp_grp_entry_t *rp_grp_entry_delete)); -extern void delete_grp_mask __P((cand_rp_t **used_cand_rp_list, - grp_mask_t **used_grp_mask_list, +extern void delete_grp_mask __P((cand_rp_t **used_cand_rp_list, + grp_mask_t **used_grp_mask_list, struct sockaddr_in6 *group_addr, struct in6_addr group_mask)); extern void delete_rp __P((cand_rp_t **used_cand_rp_list, @@ -110,7 +109,7 @@ extern void delete_rp __P((cand_rp_t **used_cand_rp_list, struct sockaddr_in6 *rp_addr)); extern void delete_rp_list __P((cand_rp_t **used_cand_rp_list, grp_mask_t **used_grp_mask_list)); -extern rpentry_t *rp_match __P((struct sockaddr_in6 *group)); +extern rpentry_t *rp_match __P((struct sockaddr_in6 *group)); extern rp_grp_entry_t *rp_grp_match __P((struct sockaddr_in6 *group)); extern rpentry_t *rp_find __P((struct sockaddr_in6 *rp_address)); extern int remap_grpentry __P((grpentry_t *grpentry_ptr)); diff --git a/usr.sbin/pim6sd/timer.c b/usr.sbin/pim6sd/timer.c index af74952e342dc..44859f203a0e2 100644 --- a/usr.sbin/pim6sd/timer.c +++ b/usr.sbin/pim6sd/timer.c @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,15 +36,16 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #include <stdlib.h> @@ -59,6 +58,7 @@ #include "debug.h" #include "rp.h" #include "pim6_proto.h" +#include "mld6.h" #include "mld6_proto.h" #include "route.h" #include "kern.h" @@ -160,7 +160,7 @@ init_timers() srcentry_save.next = (srcentry_t *) NULL; memset(&srcentry_save.address, 0, sizeof(struct sockaddr_in6)); srcentry_save.address.sin6_len = sizeof(struct sockaddr_in6); - srcentry_save.address.sin6_family= AF_INET6; + srcentry_save.address.sin6_family= AF_INET6; srcentry_save.mrtlink = (mrtentry_t *) NULL; srcentry_save.incoming = NO_VIF; srcentry_save.upstream = (pim_nbr_entry_t *) NULL; @@ -173,7 +173,7 @@ init_timers() rpentry_save.next = (rpentry_t *) NULL; memset(&rpentry_save.address, 0, sizeof(struct sockaddr_in6)); rpentry_save.address.sin6_len = sizeof(struct sockaddr_in6); - rpentry_save.address.sin6_family= AF_INET6; + rpentry_save.address.sin6_family= AF_INET6; rpentry_save.mrtlink = (mrtentry_t *) NULL; rpentry_save.incoming = NO_VIF; rpentry_save.upstream = (pim_nbr_entry_t *) NULL; @@ -214,8 +214,23 @@ age_vifs() { if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | MIFF_REGISTER)) continue; - /* Timeout neighbors */ + /* Timeout the MLD querier (unless we re the querier) */ + if ((v->uv_flags & VIFF_QUERIER) == 0 && + v->uv_querier) { /* this must be non-NULL, but check for safety. */ + IF_TIMEOUT(v->uv_querier->al_timer) { + v->uv_querier_timo++; /* count statistics */ + + /* act as a querier by myself */ + v->uv_flags |= VIFF_QUERIER; + v->uv_querier->al_addr = v->uv_linklocal->pa_addr; + v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL; + time(&v->uv_querier->al_ctime); /* reset timestamp */ + query_groups(v); + } + } + + /* Timeout neighbors */ for (curr_nbr = v->uv_pim_neighbors; curr_nbr != NULL; curr_nbr = next_nbr) { @@ -376,7 +391,7 @@ age_routes() for (cand_rp_ptr = cand_rp_list; cand_rp_ptr != (cand_rp_t *) NULL; cand_rp_ptr = cand_rp_ptr->next) { - + rpentry_ptr = cand_rp_ptr->rpentry; /* @@ -464,7 +479,7 @@ age_routes() * However, because the kernel cache/traffic info is of the * form (S,G), it is easier if we are simply collecting (S,G) * traffic all the time. - * + * * For (*,*,RP) if the number of bytes received between the last * check and now exceeds some precalculated value (based on * interchecking period and datarate threshold AND if there @@ -476,7 +491,7 @@ age_routes() * hence after a switch to the source-specific tree occurs, a * source with low datarate, but periodically sending will * keep the (S,G) states. - * + * * If a source with kernel cache entry has been idle after the * last time a check of the datarate for the whole routing * table, then delete its kernel cache entry. @@ -706,7 +721,7 @@ age_routes() &mrtentry_grp->oifs) == TRUE) { #ifdef KERNEL_MFC_WC_G -// TODO +// TODO if (kernel_cache_ptr->source == IN6ADDR_ANY_N) { @@ -877,7 +892,7 @@ age_routes() } else { - + /* iif info found */ if ((srcentry_save.incoming != @@ -956,7 +971,7 @@ age_routes() if (!(mrtentry_srcs->flags & MRTF_RP)) continue; - + /* Forwarder initiated switch */ did_switch_flag = FALSE; @@ -1031,7 +1046,7 @@ age_routes() if (src_action != PIM_ACTION_NOTHING) add_jp_entry(mrtentry_srcs->upstream, - pim_join_prune_holdtime, + pim_join_prune_holdtime, &mrtentry_srcs->group->group, SINGLE_GRP_MSK6LEN, &mrtentry_srcs->source->address, diff --git a/usr.sbin/pim6sd/timer.h b/usr.sbin/pim6sd/timer.h index 132ff5a0ed0ac..41e6f44077399 100644 --- a/usr.sbin/pim6sd/timer.h +++ b/usr.sbin/pim6sd/timer.h @@ -25,8 +25,6 @@ * 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$ */ /* * Questions concerning this software should be directed to @@ -34,47 +32,48 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * + * $FreeBSD$ */ #ifndef TIMER_H -#define TIMER_H +#define TIMER_H /* the default granularity if not specified in the config file */ -#define DEFAULT_TIMER_INTERVAL 5 +#define DEFAULT_TIMER_INTERVAL 5 /* For timeout. The timers count down */ -#define SET_TIMER(timer, value) (timer) = (value) -#define RESET_TIMER(timer) (timer) = 0 -#define COPY_TIMER(timer_1, timer_2) (timer_2) = (timer_1) -#define IF_TIMER_SET(timer) if ((timer) > 0) -#define IF_TIMER_NOT_SET(timer) if ((timer) <= 0) -#define FIRE_TIMER(timer) (timer) = 0 +#define SET_TIMER(timer, value) (timer) = (value) +#define RESET_TIMER(timer) (timer) = 0 +#define COPY_TIMER(timer_1, timer_2) (timer_2) = (timer_1) +#define IF_TIMER_SET(timer) if ((timer) > 0) +#define IF_TIMER_NOT_SET(timer) if ((timer) <= 0) +#define FIRE_TIMER(timer) (timer) = 0 -#define IF_TIMER_NOT_SET(timer) if ((timer) <= 0) +#define IF_TIMER_NOT_SET(timer) if ((timer) <= 0) -#define IF_TIMEOUT(timer) \ +#define IF_TIMEOUT(timer) \ if (!((timer) -= (MIN(timer, timer_interval)))) -#define IF_NOT_TIMEOUT(timer) \ +#define IF_NOT_TIMEOUT(timer) \ if ((timer) -= (MIN(timer, timer_interval))) -#define TIMEOUT(timer) \ +#define TIMEOUT(timer) \ (!((timer) -= (MIN(timer, timer_interval)))) - -#define NOT_TIMEOUT(timer) \ + +#define NOT_TIMEOUT(timer) \ ((timer) -= (MIN(timer, timer_interval))) @@ -92,11 +91,11 @@ extern u_int32 pim_register_suppression_timeout; extern u_int32 pim_register_probe_time; extern u_int32 pim_assert_timeout; -extern void init_timers __P(()); -extern void init_timers __P(()); -extern void age_vifs __P(()); -extern void age_routes __P(()); -extern void age_misc __P(()); +extern void init_timers __P((void)); +extern void init_timers __P((void)); +extern void age_vifs __P((void)); +extern void age_routes __P((void)); +extern void age_misc __P((void)); #endif diff --git a/usr.sbin/pim6sd/trace.c b/usr.sbin/pim6sd/trace.c index 7c54628bbda4e..f13abae730f71 100644 --- a/usr.sbin/pim6sd/trace.c +++ b/usr.sbin/pim6sd/trace.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -47,7 +47,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -57,11 +57,9 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: trace.c,v 1.7 1999/09/16 08:45:45 jinmei Exp $ @@ -74,6 +72,7 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #include <sys/types.h> @@ -226,9 +225,9 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) } else log(LOG_DEBUG, 0, "...no route"); } - + /* - * Query type packet - check if rte exists + * Query type packet - check if rte exists * Check if the query destination is a vif connected to me. * and if so, whether I should start response back */ @@ -262,7 +261,7 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) #endif } vifi = find_vif_direct(&dst_sa6); - + if (vifi == NO_VIF) { /* * The traceroute destination is not on one of @@ -300,21 +299,21 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) "Wrong interface for packet"); errcode = TR_WRONG_IF; } - } - + } + /* Now that we've decided to send a response, save the qid */ oqid = qry->tr_qid; IF_DEBUG(DEBUG_TRACE) log(LOG_DEBUG, 0, "Sending traceroute response"); - + /* copy the packet to the sending buffer */ p = mld6_send_buf + sizeof(struct mld6_hdr); - + bcopy(data, p, datalen); - + p += datalen; - + /* * If there is no room to insert our reply, coopt the previous hop * error indication to relay this fact. @@ -333,7 +332,7 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) bzero(resp, sizeof(struct tr6_resp)); datalen += (RLEN + sizeof(struct mld6_hdr)); - resp->tr_qarr = htonl(((tp.tv_sec + JAN_1970) << 16) + + resp->tr_qarr = htonl(((tp.tv_sec + JAN_1970) << 16) + ((tp.tv_usec << 10) / 15625)); resp->tr_rproto = PROTO_PIM; @@ -551,7 +550,7 @@ accept_mtrace(src, dst, group, ifindex, data, no, datalen) "reply" : "request on", inet6_fmt(dst), sa6 ? inet6_fmt(&sa6->sin6_addr) : "unspecified"); - + send_mld6(resptype, no, sa6, &resp_sa6, group, ifindex, 0, datalen, 0); } diff --git a/usr.sbin/pim6sd/trace.h b/usr.sbin/pim6sd/trace.h index 465acc693db16..4a5aa6badd22e 100644 --- a/usr.sbin/pim6sd/trace.h +++ b/usr.sbin/pim6sd/trace.h @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -47,7 +47,7 @@ * ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. 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, TITLE, AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND * NON-INFRINGEMENT. * * IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY @@ -57,11 +57,9 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* - * Questions concerning this software should be directed to + * Questions concerning this software should be directed to * Pavlin Ivanov Radoslavov (pavlin@catarina.usc.edu) * * $Id: trace.h,v 1.2 1999/09/09 15:47:11 jinmei Exp $ @@ -74,10 +72,11 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #ifndef TRACE_H -#define TRACE_H +#define TRACE_H /* * The packet format for a traceroute request. @@ -99,8 +98,8 @@ struct tr6_query { #endif /* BYTE_ORDER */ }; -#define tr_rhlim q.rhlim -#define tr_qid q.qid +#define tr_rhlim q.rhlim +#define tr_qid q.qid /* * Traceroute response format. A traceroute response has a tr_query at the @@ -129,60 +128,60 @@ struct tr6_resp { }; /* defs within mtrace */ -#define QUERY 1 -#define RESP 2 -#define QLEN sizeof(struct tr6_query) -#define RLEN sizeof(struct tr6_resp) +#define QUERY 1 +#define RESP 2 +#define QLEN sizeof(struct tr6_query) +#define RLEN sizeof(struct tr6_resp) /* fields for tr_inifid and tr_outifid */ -#define TR_NO_VIF 0xffffffff/* interface can't be determined */ +#define TR_NO_VIF 0xffffffff/* interface can't be determined */ /* fields for tr_rflags (forwarding error codes) */ -#define TR_NO_ERR 0 /* No error */ -#define TR_WRONG_IF 1 /* traceroute arrived on non-oif */ -#define TR_PRUNED 2 /* router has sent a prune upstream */ -#define TR_OPRUNED 3 /* stop forw. after request from next hop rtr*/ -#define TR_SCOPED 4 /* group adm. scoped at this hop */ -#define TR_NO_RTE 5 /* no route for the source */ -#define TR_NO_LHR 6 /* not the last-hop router */ -#define TR_NO_FWD 7 /* not forwarding for this (S,G). Reason = ? */ -#define TR_RP 8 /* I am the RP/Core */ -#define TR_IIF 9 /* request arrived on the iif */ -#define TR_NO_MULTI 0x0a /* multicast disabled on that interface */ -#define TR_NO_SPACE 0x81 /* no space to insert responce data block */ -#define TR_OLD_ROUTER 0x82 /* previous hop does not support traceroute */ -#define TR_ADMIN_PROHIB 0x83 /* traceroute adm. prohibited */ +#define TR_NO_ERR 0 /* No error */ +#define TR_WRONG_IF 1 /* traceroute arrived on non-oif */ +#define TR_PRUNED 2 /* router has sent a prune upstream */ +#define TR_OPRUNED 3 /* stop forw. after request from next hop rtr*/ +#define TR_SCOPED 4 /* group adm. scoped at this hop */ +#define TR_NO_RTE 5 /* no route for the source */ +#define TR_NO_LHR 6 /* not the last-hop router */ +#define TR_NO_FWD 7 /* not forwarding for this (S,G). Reason = ? */ +#define TR_RP 8 /* I am the RP/Core */ +#define TR_IIF 9 /* request arrived on the iif */ +#define TR_NO_MULTI 0x0a /* multicast disabled on that interface */ +#define TR_NO_SPACE 0x81 /* no space to insert responce data block */ +#define TR_OLD_ROUTER 0x82 /* previous hop does not support traceroute */ +#define TR_ADMIN_PROHIB 0x83 /* traceroute adm. prohibited */ /* fields for tr_flags */ -#define TR_SUBNET_COUNT 0x80 /* pkt count for (S,G) is for source network */ +#define TR_SUBNET_COUNT 0x80 /* pkt count for (S,G) is for source network */ /* fields for r_plen */ -#define TR_GROUP_ONLY 0xff /* forwarding solely on group state */ +#define TR_GROUP_ONLY 0xff /* forwarding solely on group state */ /* fields for packets count */ -#define TR_CANT_COUNT 0xffffffff /* no count can be reported */ +#define TR_CANT_COUNT 0xffffffff /* no count can be reported */ /* fields for tr_rproto (routing protocol) */ -#define PROTO_DVMRP 1 -#define PROTO_MOSPF 2 -#define PROTO_PIM 3 -#define PROTO_CBT 4 -#define PROTO_PIM_SPECIAL 5 -#define PROTO_PIM_STATIC 6 -#define PROTO_DVMRP_STATIC 7 +#define PROTO_DVMRP 1 +#define PROTO_MOSPF 2 +#define PROTO_PIM 3 +#define PROTO_CBT 4 +#define PROTO_PIM_SPECIAL 5 +#define PROTO_PIM_STATIC 6 +#define PROTO_DVMRP_STATIC 7 -#define MASK_TO_VAL(x, i) { \ +#define MASK_TO_VAL(x, i) { \ u_int32_t _x = ntohl(x); \ (i) = 1; \ while ((_x) <<= 1) \ (i)++; \ }; -#define VAL_TO_MASK(x, i) { \ +#define VAL_TO_MASK(x, i) { \ x = htonl(~((1 << (32 - (i))) - 1)); \ }; -#define MASKLEN_TO_MASK6(masklen, mask6) \ +#define MASKLEN_TO_MASK6(masklen, mask6) \ do {\ u_char maskarray[8] = \ {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; \ @@ -198,13 +197,13 @@ struct tr6_resp { /* obnoxious gcc gives an extraneous warning about this constant... */ #if defined(__STDC__) || defined(__GNUC__) -#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ +#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */ #else -#define JAN_1970 2208988800L /* 1970 - 1900 in seconds */ -#define const /**/ +#define JAN_1970 2208988800L /* 1970 - 1900 in seconds */ +#define const /**/ #endif -#define NBR_VERS(n) (((n)->al_pv << 8) + (n)->al_mv) +#define NBR_VERS(n) (((n)->al_pv << 8) + (n)->al_mv) void accept_mtrace __P((struct sockaddr_in6 *, struct in6_addr *, struct in6_addr *, int, char *, u_int, int)); diff --git a/usr.sbin/pim6sd/var.h b/usr.sbin/pim6sd/var.h index 999ba44060725..93556e00f6261 100644 --- a/usr.sbin/pim6sd/var.h +++ b/usr.sbin/pim6sd/var.h @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -31,32 +31,32 @@ /* YIPS @(#)$Id: var.h,v 1.1 1999/10/29 09:04:54 jinmei Exp $ */ #if !defined(_VAR_H_) -#define _VAR_H_ +#define _VAR_H_ #include <sys/socket.h> -#define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c)) +#define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c)) -#define CALLOC(size, cast) (cast)calloc(1, (size)) +#define CALLOC(size, cast) (cast)calloc(1, (size)) -#define ISSET(exp, bit) (((exp) & (bit)) == (bit)) +#define ISSET(exp, bit) (((exp) & (bit)) == (bit)) -#define ATOX(c) \ +#define ATOX(c) \ (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) -#define LALIGN(a) \ +#define LALIGN(a) \ ((a) > 0 ? ((a) &~ (sizeof(long) - 1)) : sizeof(long)) -#define RNDUP(a) \ +#define RNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) -#define BUFADDRSIZE 128 -#define INET_NTOP(addr, buf) \ +#define BUFADDRSIZE 128 +#define INET_NTOP(addr, buf) \ inet_ntop(((struct sockaddr *)(addr))->sa_family, _INADDRBYSA(addr), buf, sizeof(buf)) -#define GETNAMEINFO(x, y, z) \ +#define GETNAMEINFO(x, y, z) \ getnameinfo((x), (x)->sa_len, (y), sizeof(y), (z), sizeof(z), \ NI_NUMERICHOST | NI_NUMERICSERV) -#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) +#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) #endif /*!defined(_VAR_H_)*/ diff --git a/usr.sbin/pim6sd/vif.c b/usr.sbin/pim6sd/vif.c index e7ef2d9fc5879..2664e46571b9f 100644 --- a/usr.sbin/pim6sd/vif.c +++ b/usr.sbin/pim6sd/vif.c @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,12 +36,12 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * @@ -56,6 +54,7 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #include <sys/ioctl.h> @@ -87,13 +86,13 @@ int total_interfaces; if_set if_nullset; if_set if_result; -int init_reg_vif(); -void start_all_vifs(); -void start_vif( vifi_t vifi ); -void stop_vif( vifi_t vivi ); -int update_reg_vif( vifi_t register_vifi); +int init_reg_vif __P((void)); +void start_all_vifs __P((void)); +void start_vif __P((vifi_t vifi)); +void stop_vif __P((vifi_t vivi)); +int update_reg_vif __P((vifi_t register_vifi)); -extern int cfparse(int, int); +extern int cfparse __P((int, int)); void init_vifs() { @@ -173,7 +172,7 @@ void init_vifs() enabled_vifs == 0 ? "no enabled vifs" : "only one enabled vif" ); memset(&if_nullset,0,sizeof(if_nullset)); - k_init_pim(mld6_socket); + k_init_pim(mld6_socket); IF_DEBUG(DEBUG_PIM_DETAIL) log(LOG_DEBUG,0,"Pim kernel initialization done"); @@ -224,7 +223,7 @@ int init_reg_vif() return -1; } - + memcpy(v,&uvifs[i],sizeof(*v)); strncpy(v->uv_name,"register_mif0",IFNAMSIZ); v->uv_flags = MIFF_REGISTER; @@ -240,7 +239,7 @@ int init_reg_vif() numvifs++; total_interfaces++; - return 0; + return 0; } void start_all_vifs() @@ -268,17 +267,17 @@ void start_all_vifs() IF_DEBUG(DEBUG_IF) { if ( v-> uv_flags & VIFF_DISABLED) - log(LOG_DEBUG,0,"%s is DISABLED ; vif #%u out of service",v->uv_name,vifi); + log(LOG_DEBUG,0,"%s is DISABLED ; vif #%u out of service",v->uv_name,vifi); else log(LOG_DEBUG,0,"%s is DOWN ; vif #%u out of service",v->uv_name,vifi); - } + } } else start_vif(vifi); } if ( action == MIFF_REGISTER) break; - } + } } /* @@ -311,45 +310,46 @@ void start_vif (vifi_t vifi) IF_DEBUG(DEBUG_IF) log(LOG_DEBUG,0,"%s comes up ,vif #%u now in service",v->uv_name,vifi); - if(!(v->uv_flags & MIFF_REGISTER)) - { - - /* - * Join the PIM multicast group on the interface. - */ - - - k_join(mld6_socket,&allpim6routers_group.sin6_addr,v->uv_ifindex); - /* - * Join the ALL-ROUTERS multicast group on the interface. - * This allows mtrace requests to loop back if they are run - * on the multicast router.this allow receiving mld6 messages too. - */ - - k_join(mld6_socket,&allrouters_group.sin6_addr,v->uv_ifindex); - - /* - * Until neighbors are discovered, assume responsibility for sending - * periodic group membership queries to the subnet. Send the first - * query. - */ - - - v->uv_flags |= VIFF_QUERIER; - query_groups(v); + if (!(v->uv_flags & MIFF_REGISTER)) { + /* + * Join the PIM multicast group on the interface. + */ + k_join(mld6_socket, &allpim6routers_group.sin6_addr, + v->uv_ifindex); - /* - * Send a probe via the new vif to look for neighbors. - */ + /* + * Join the ALL-ROUTERS multicast group on the interface. + * This allows mtrace requests to loop back if they are run + * on the multicast router.this allow receiving mld6 messages too. + */ + k_join(mld6_socket, &allrouters_group.sin6_addr, v->uv_ifindex); - send_pim6_hello( v , pim_hello_holdtime ); + /* + * Until neighbors are discovered, assume responsibility for sending + * periodic group membership queries to the subnet. Send the first + * query. + */ + v->uv_flags |= VIFF_QUERIER; + if (!v->uv_querier) { + v->uv_querier = (struct listaddr *)malloc(sizeof(struct listaddr)); + memset(v->uv_querier, 0, sizeof(struct listaddr)); + } + v->uv_querier->al_addr = v->uv_linklocal->pa_addr; + v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL; + time(&v->uv_querier->al_ctime); /* reset timestamp */ + query_groups(v); + + /* + * Send a probe via the new vif to look for neighbors. + */ + send_pim6_hello(v, pim_hello_holdtime); } } /* * Stop a vif (either physical interface, tunnel or * register.) If we are running only PIM we don't have tunnels. - */ + */ void stop_vif( vifi_t vifi ) @@ -360,7 +360,7 @@ void stop_vif( vifi_t vifi ) register pim_nbr_entry_t *next; struct vif_acl *acl; - + /* * TODO: make sure that the kernel viftable is * consistent with the daemon table @@ -411,7 +411,7 @@ void stop_vif( vifi_t vifi ) v->uv_pim_neighbors=NULL; } - + /* TODO: currently not used */ /* The Access Control List (list with the scoped addresses) */ @@ -497,7 +497,7 @@ max_global_address() &p->pa_addr) && !IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr) && !IN6_IS_ADDR_SITELOCAL(&p->pa_addr.sin6_addr)) - pmax=p; + pmax=p; } } } @@ -522,7 +522,7 @@ uv_global(vifi) } /* - * Check if the interface exists in the mif table. If true + * Check if the interface exists in the mif table. If true * return the highest address of the interface else return NULL. */ struct sockaddr_in6 * @@ -562,12 +562,12 @@ local_iface(char *ifname) return NULL; } -/* +/* * See if any interfaces have changed from up state to down, or vice versa, * including any non-multicast-capable interfaces that are in use as local * tunnel end-points. Ignore interfaces that have been administratively * disabled. - */ + */ void check_vif_state() { @@ -596,7 +596,7 @@ check_vif_state() continue; strncpy( ifr.ifr_name , v->uv_name , IFNAMSIZ ); - + /* get the interface flags */ if( ioctl( udp_socket , SIOCGIFFLAGS , (char *)&ifr )<0 ) log(LOG_ERR, errno, @@ -675,12 +675,12 @@ find_vif_direct(src) vifi_t vifi; register struct uvif *v; register struct phaddr *p; - - for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) + + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | VIFF_TUNNEL|MIFF_REGISTER)) continue; - for (p = v->uv_addrs; p; p = p->pa_next) + for (p = v->uv_addrs; p; p = p->pa_next) { if (inet6_equal(src, &p->pa_addr)) return(NO_VIF); @@ -706,40 +706,40 @@ local_address(src) register struct phaddr *p; for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { - if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | MIFF_REGISTER)) - continue; - for (p = v->uv_addrs; p; p = p->pa_next) { - if (inet6_equal(src, &p->pa_addr)) - return(vifi); - } + if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | MIFF_REGISTER)) + continue; + for (p = v->uv_addrs; p; p = p->pa_next) { + if (inet6_equal(src, &p->pa_addr)) + return(vifi); + } } /* Returning NO_VIF means not a local address */ return (NO_VIF); } -/* +/* * If the source is directly connected, or is local address, * find the vif number for the corresponding physical interface * (tunnels excluded). * Return the vif number or NO_VIF if not found. - */ + */ vifi_t find_vif_direct_local(src) struct sockaddr_in6 *src; -{ +{ vifi_t vifi; - register struct uvif *v; + register struct uvif *v; register struct phaddr *p; - + for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | VIFF_TUNNEL |MIFF_REGISTER)) continue; for (p = v->uv_addrs; p; p = p->pa_next) { if (inet6_equal(src, &p->pa_addr) || - inet6_match_prefix(src, &p->pa_prefix, &p->pa_subnetmask)) + inet6_match_prefix(src, &p->pa_prefix, &p->pa_subnetmask)) return(vifi); } } @@ -755,7 +755,7 @@ vif_forwarder(if_set *p1 , if_set *p2) { if (p1->ifs_bits[idx] & p2->ifs_bits[idx]) return(TRUE); - + } /* (p1 & p2) is empty. We're not the forwarder */ @@ -792,15 +792,15 @@ vif_xor(if_set *p1 , if_set *p2, if_set *result) return(result); } -/* +/* * stop all vifs - */ + */ void stop_all_vifs() { vifi_t vifi; struct uvif *v; - + for (vifi = 0, v=uvifs; vifi < numvifs; ++vifi, ++v) { if (!(v->uv_flags & VIFF_DOWN)) { stop_vif(vifi); diff --git a/usr.sbin/pim6sd/vif.h b/usr.sbin/pim6sd/vif.h index f3e349587c329..d81d65794e608 100644 --- a/usr.sbin/pim6sd/vif.h +++ b/usr.sbin/pim6sd/vif.h @@ -29,8 +29,6 @@ * * Other copyrights might apply to parts of this software and are so * noted when applicable. - * - * $FreeBSD$ */ /* * Questions concerning this software should be directed to @@ -38,12 +36,12 @@ * */ /* - * This program has been derived from pim6dd. + * This program has been derived from pim6dd. * The pim6dd program is covered by the license in the accompanying file * named "LICENSE.pim6dd". */ /* - * This program has been derived from pimd. + * This program has been derived from pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * @@ -56,10 +54,11 @@ * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of * Leland Stanford Junior University. * + * $FreeBSD$ */ #ifndef VIF_H -#define VIF_H +#define VIF_H #include <sys/param.h> #include <sys/time.h> @@ -76,41 +75,41 @@ extern int total_interfaces; extern int udp_socket; extern struct uvif uvifs[]; extern vifi_t numvifs; -extern int vifs_down; +extern int vifs_down; extern int phys_vif; extern vifi_t reg_vif_num; -#define NO_VIF ((vifi_t)MAXVIFS) /* An invalid vif index */ -#define DEFAULT_METRIC 1 -#define VIFF_DOWN 0x000100 -#define VIFF_DISABLED 0x000200 -#define VIFF_QUERIER 0x000400 -#define VIFF_REXMIT_PRUNES 0x004000 -#define VIFF_DR 0x040000 -#define VIFF_NONBRS 0x080000 -#define VIFF_PIM_NBR 0x200000 -#define VIFF_POINT_TO_POINT 0x400000 -#define NBRTYPE u_long -#define NBRBITS sizeof(NBRTYPE) *8 +#define NO_VIF ((vifi_t)MAXVIFS) /* An invalid vif index */ +#define DEFAULT_METRIC 1 +#define VIFF_DOWN 0x000100 +#define VIFF_DISABLED 0x000200 +#define VIFF_QUERIER 0x000400 +#define VIFF_REXMIT_PRUNES 0x004000 +#define VIFF_DR 0x040000 +#define VIFF_NONBRS 0x080000 +#define VIFF_PIM_NBR 0x200000 +#define VIFF_POINT_TO_POINT 0x400000 +#define NBRTYPE u_long +#define NBRBITS sizeof(NBRTYPE) *8 extern if_set if_nullset; -#define IF_ISEMPTY(p) (memcmp((p), &if_nullset, sizeof(if_nullset)) == 0) -#define IF_SAME(p1, p2) (memcmp((p1),(p2),sizeof(*(p1))) == 0) -#define IF_CLR_MASK(p, mask) \ +#define IF_ISEMPTY(p) (memcmp((p), &if_nullset, sizeof(if_nullset)) == 0) +#define IF_SAME(p1, p2) (memcmp((p1),(p2),sizeof(*(p1))) == 0) +#define IF_CLR_MASK(p, mask) \ {\ int idx;\ for (idx = 0; idx < sizeof(*(p))/sizeof(fd_mask); idx++) {\ (p)->ifs_bits[idx] &= ~((mask)->ifs_bits[idx]);\ }\ } -#define IF_MERGE(p1, p2, result) \ +#define IF_MERGE(p1, p2, result) \ {\ int idx;\ for (idx = 0; idx < sizeof(*(p1))/sizeof(fd_mask); idx++) {\ (result)->ifs_bits[idx] = (p1)->ifs_bits[idx]|(p2)->ifs_bits[idx]; \ }\ - } + } typedef struct { NBRTYPE hi; @@ -122,12 +121,12 @@ struct vf_element { struct sockaddr_in6 *vfe_addr; struct in6_addr vfe_mask; int vfe_flags; -#define VFRF_EXACT 0x0001 +#define VFRF_EXACT 0x0001 }; -#define VFT_ACCEPT 1 -#define VFT_DENY 2 -#define VFF_BIDIR 1 +#define VFT_ACCEPT 1 +#define VFT_DENY 2 +#define VFF_BIDIR 1 struct vif_filter { int vf_type; @@ -143,9 +142,9 @@ struct listaddr { union { u_int32 alu_genid; /* generation id for neighbor */ struct sockaddr_in6 alu_reporter; /* a host which reported membership */ - } al_alu; + } al_alu; u_char al_pv; /* router protocol version */ - u_char al_mv; /* router mrouted version */ + u_char al_mv; /* router mrouted version */ u_char al_old; /* time since heard old report */ u_char al_index; /* neighbor index */ u_long al_timerid; /* timer for group membership */ @@ -153,15 +152,15 @@ struct listaddr { u_int16 al_flags; /* flags related to this neighbor */ }; -#define al_genid al_alu.alu_genid -#define al_reporter al_alu.alu_reporter +#define al_genid al_alu.alu_genid +#define al_reporter al_alu.alu_reporter /* - * User level Virtual Interface structure + * User level Virtual Interface structure * * A "virtual interface" is either a physical, multicast-capable interface * (called a "phyint"), a virtual point-to-point link (called a "tunnel") - * or a "register vif" used by PIM. The register vif is used by the + * or a "register vif" used by PIM. The register vif is used by the * Designated Router (DR) to send encapsulated data packets to the * Rendevous Point (RP) for a particular group. The data packets are * encapsulated in PIM messages (IPPROTO_PIM = 103) and then unicast to @@ -169,34 +168,34 @@ struct listaddr { * (Note: all addresses, subnet numbers and masks are kept in NETWORK order.) */ struct uvif { - u_int uv_flags; + u_int uv_flags; u_char uv_metric; /* VIFF_ flags defined below */ u_char uv_admetric; /* advertised cost of this vif */ u_int uv_rate_limit; /* rate limit on this vif */ struct phaddr *uv_linklocal; /* link-local address of this vif */ - struct sockaddr_in6 uv_rmt_addr;/* remote end-point addr (tunnels only) */ - struct sockaddr_in6 uv_dst_addr;/* destination for PIM messages */ - struct sockaddr_in6 uv_prefix; /* prefix (phyints only) */ - struct in6_addr uv_subnetmask; /* subnet mask (phyints only) */ + struct sockaddr_in6 uv_rmt_addr;/* remote end-point addr (tunnels only) */ + struct sockaddr_in6 uv_dst_addr;/* destination for PIM messages */ + struct sockaddr_in6 uv_prefix; /* prefix (phyints only) */ + struct in6_addr uv_subnetmask; /* subnet mask (phyints only) */ - char uv_name[IFNAMSIZ]; /* interface name */ + char uv_name[IFNAMSIZ]; /* interface name */ u_int uv_ifindex; /* index of the interface */ u_int uv_siteid; /* index of the site on the interface */ struct listaddr *uv_groups; /* list of local groups (phyints only) */ struct lisaddr *uv_dvmrp_neighbors; nbrbitmap_t uv_nbrmap; /* bitmap of active neighboring routers */ - struct listaddr *uv_querier; /* MLD querier on vif */ + struct listaddr *uv_querier; /* MLD querier on vif */ int uv_prune_lifetime; /* Prune lifetime or 0 for default */ - struct vif_acl *uv_acl; /* access control list of groups */ + struct vif_acl *uv_acl; /* access control list of groups */ int uv_leaftimer; /* time until this vif is considrd leaf */ struct phaddr *uv_addrs; /* Additional addresses on this vif */ struct vif_filter *uvfilter; /* Route filters on this vif */ u_int16 uv_pim_hello_timer; /* timer for sending PIM hello msgs */ u_int16 uv_gq_timer; /* Group Query timer */ - u_int16 uv_jp_timer; /* Join/Prune timer */ - int uv_local_pref; /* default local preference for assert */ + u_int16 uv_jp_timer; /* Join/Prune timer */ + int uv_local_pref; /* default local preference for assert */ int uv_local_metric; /* default local metric for assert */ struct pim_nbr_entry *uv_pim_neighbors; /* list of PIM nbr routers */ @@ -227,6 +226,7 @@ struct uvif { /* occurrences of timeouts */ u_quad_t uv_pim6_nbr_timo; u_quad_t uv_listener_timo; + u_quad_t uv_querier_timo; u_quad_t uv_outif_timo; /* outgoing interfaces timers */ }; @@ -239,7 +239,7 @@ struct phaddr { /* The Access Control List (list with scoped addresses) member */ -#define VIFF_NOLISTENER 0x800000 /* no listener on the link */ +#define VIFF_NOLISTENER 0x800000 /* no listener on the link */ struct vif_acl { struct vif_acl *acl_next; @@ -247,7 +247,7 @@ struct vif_acl { struct in6_addr acl_mask; }; -/* +/* * Used to get the RPF neighbor and IIF info * for a given source from the unicast routing table. */ @@ -256,22 +256,22 @@ struct rpfctl { struct sockaddr_in6 source; /* the source for which we want iif and rpfnbr */ struct sockaddr_in6 rpfneighbor;/* next hop towards the source */ vifi_t iif; /* the incoming interface to reach the next hop */ -}; +}; -extern void init_vifs __P(()); -extern void stop_all_vifs __P(()); -extern void check_vif_state __P(()); -struct sockaddr_in6 * max_global_address(); -struct sockaddr_in6 * uv_global __P(()); +extern void init_vifs __P((void)); +extern void stop_all_vifs __P((void)); +extern void check_vif_state __P((void)); +struct sockaddr_in6 * max_global_address __P((void)); +struct sockaddr_in6 * uv_global __P((vifi_t)); extern vifi_t local_address __P((struct sockaddr_in6 *src)); -struct sockaddr_in6 * local_iface( char *ifname ); +struct sockaddr_in6 * local_iface __P((char *ifname)); extern vifi_t find_vif_direct __P((struct sockaddr_in6 *src)); extern vifi_t find_vif_direct_local __P((struct sockaddr_in6 *src)); extern int vif_forwarder __P((if_set *p1 ,if_set *p2)); -extern if_set *vif_and __P((if_set *p1, if_set *p2, if_set *result)); +extern if_set *vif_and __P((if_set *p1, if_set *p2, if_set *result)); extern if_set *vif_xor __P((if_set *p1, if_set *p2, if_set *result)); extern struct uvif *find_vif __P((char *ifname)); #endif diff --git a/usr.sbin/pim6sd/vmbuf.h b/usr.sbin/pim6sd/vmbuf.h index 01fa8cde58907..b6931dddefc10 100644 --- a/usr.sbin/pim6sd/vmbuf.h +++ b/usr.sbin/pim6sd/vmbuf.h @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -45,5 +45,5 @@ extern void vfree(vchar_t *); extern vchar_t *vdup(vchar_t *); extern int pvdump(vchar_t *); -#define VREALLOC(ptr, size) ((ptr) = vrealloc((ptr), (size))) +#define VREALLOC(ptr, size) ((ptr) = vrealloc((ptr), (size))) diff --git a/usr.sbin/prefix/prefix.8 b/usr.sbin/prefix/prefix.8 index e78ee686f6853..70a1e9ea10514 100644 --- a/usr.sbin/prefix/prefix.8 +++ b/usr.sbin/prefix/prefix.8 @@ -1,6 +1,6 @@ .\" 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: @@ -12,7 +12,7 @@ .\" 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 @@ -25,7 +25,7 @@ .\" 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 $ +.\" $Id: prefix.8,v 1.4 2000/05/31 17:00:08 itojun Exp $ .\" $FreeBSD$ .\" .Dd October 10, 1998 @@ -36,37 +36,62 @@ .Nd configure network interface prefixes .Sh SYNOPSIS .Nm prefix +.Bk -words .Ar interface prefix +.Ek +.Bk -words .Op Ar parameters +.Ek +.Bk -words .Op Cm set | delete +.Ek .Nm prefix +.Bk -words +.Ek .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 +.Ek +.Bk -words +.Cm matchpr Ar match_prefix +.Ek +.Bk -words +.Cm mp_len Ar match_prefix_len +.Ek +.Bk -words +.Cm usepr Ar use_prefix +.Ek +.Bk -words +.Cm up_uselen Ar use_prefix_len +.Ek +.Bk -words .Op Ar parameters +.Ek +.Bk -words .Op Cm add | change | setglobal +.Ek .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 +.Bk -words +.Cm matchpr Ar match_prefix +.Ek +.Bk -words +.Cm mp_len Ar match_prefix_len +.Ek +.Bk -words +.Cm usepr Ar use_prefix +.Ek +.Bk -words +.Cm up_uselen Ar use_prefix_uselen +.Ek +.Bk -words .Op Ar parameters +.Ek +.Bk -words .Op Cm add | change | setglobal +.Ek .Sh DESCRIPTION -.Nm Prefix +.Nm is used to assign an prefix to a network interface and/or renumbering network interface prefixes. @@ -104,7 +129,7 @@ to a network interface. Specify that .Ar len bits are reserved as identifier for IPv6 sub-networks in -.Ar prefix . +.Ar prefix. The .Ar len must be integer, and for syntactical reason it must be between 0 to 128. @@ -147,11 +172,11 @@ 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 medium part of +Specify the midium part of .Ar use_prefix just next to the starting part specified by -.Ar use_prefix_uselen , -as decimal bit number. +.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 @@ -173,7 +198,7 @@ as prefix valid life time for a prefix to be added. Valid value for .Ar time is same as for -.Cm pltime . +.Cm pltime. .It Cm raf_auto Enable the autonomous address auto configuration for the prefix to be added. diff --git a/usr.sbin/prefix/prefix.c b/usr.sbin/prefix/prefix.c index 04bd9a1d7182a..84fbf26d2c4ca 100644 --- a/usr.sbin/prefix/prefix.c +++ b/usr.sbin/prefix/prefix.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -36,7 +36,9 @@ #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> @@ -55,8 +57,8 @@ #include <string.h> #include <unistd.h> -#define DEF_ADVVALIDLIFETIME 2592000 -#define DEF_ADVPREFERREDLIFETIME 604800 +#define DEF_ADVVALIDLIFETIME 2592000 +#define DEF_ADVPREFERREDLIFETIME 604800 struct in6_prefixreq prereq = {{NULL}, /* interface name */ PR_ORIG_STATIC, 64, /* default plen */ @@ -81,7 +83,7 @@ struct in6_rrenumreq rrreq = {{NULL}, /* interface name */ {NULL} /* use prefix */ }; -#define C(x) ((caddr_t) &x) +#define C(x) ((caddr_t) &x) struct prefix_cmds { const char *errmsg; @@ -95,12 +97,12 @@ struct prefix_cmds { {"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 +#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 */ @@ -110,8 +112,6 @@ 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)); @@ -251,7 +251,7 @@ main(argc, argv) while (next < lim) { ifm = (struct if_msghdr *)next; - + if (ifm->ifm_type == RTM_IFINFO) { sdl = (struct sockaddr_dl *)(ifm + 1); flags = ifm->ifm_flags; @@ -379,9 +379,9 @@ prefix(int argc, char *const *argv) close(s); return(0); } -#define PREFIX 0 -#define MPREFIX 1 -#define UPREFIX 2 +#define PREFIX 0 +#define MPREFIX 1 +#define UPREFIX 2 void Perror(cmd) @@ -402,7 +402,7 @@ Perror(cmd) } } -#define SIN6(x) ((struct sockaddr_in6 *) &(x)) +#define SIN6(x) ((struct sockaddr_in6 *) &(x)) struct sockaddr_in6 *sin6tab[] = { SIN6(prereq.ipr_prefix), SIN6(rrreq.irr_matchprefix), SIN6(rrreq.irr_useprefix)}; diff --git a/usr.sbin/rip6query/Makefile b/usr.sbin/rip6query/Makefile index 8a0cd40147a38..4257e98b97778 100644 --- a/usr.sbin/rip6query/Makefile +++ b/usr.sbin/rip6query/Makefile @@ -1,3 +1,4 @@ +# $NetBSD: Makefile,v 1.7 1995/03/18 14:56:21 cgd Exp $ # @(#)Makefile 8.1 (Berkeley) 6/5/93 # $FreeBSD$ diff --git a/usr.sbin/rip6query/rip6query.8 b/usr.sbin/rip6query/rip6query.8 index bd64068d3575b..d77e6d0d11fb1 100644 --- a/usr.sbin/rip6query/rip6query.8 +++ b/usr.sbin/rip6query/rip6query.8 @@ -1,7 +1,7 @@ .\" .\" 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: @@ -13,7 +13,7 @@ .\" 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 @@ -26,12 +26,12 @@ .\" 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 $ +.\" $Id: rip6query.8,v 1.2 2000/01/19 06:24:55 itojun Exp $ .\" $FreeBSD$ .\" .Dd Oct 7, 1999 .Dt RIP6QUERY 8 -.Os KAME +.Os .Sh NAME .Nm rip6query .Nd RIPng debugging tool @@ -54,7 +54,7 @@ and is useful when link-local address is specified for .Ar destination . .\" .Sh SEE ALSO -.Xr route6d 8 . +.Xr route6d 8 .\" .Sh HISTORY The diff --git a/usr.sbin/rip6query/rip6query.c b/usr.sbin/rip6query/rip6query.c index 523b17f149d83..ed0f6f98765c8 100644 --- a/usr.sbin/rip6query/rip6query.c +++ b/usr.sbin/rip6query/rip6query.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -36,12 +36,15 @@ #include <string.h> #include <ctype.h> #include <signal.h> +#include <errno.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> @@ -51,11 +54,10 @@ /* wrapper for KAME-special getnameinfo() */ #ifndef NI_WITHSCOPEID -#define NI_WITHSCOPEID 0 +#define NI_WITHSCOPEID 0 #endif int s; -extern int errno; struct sockaddr_in6 sin6; struct rip6 *ripbuf; @@ -75,8 +77,6 @@ main(argc, argv) 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]; @@ -114,14 +114,10 @@ main(argc, argv) snprintf(pbuf, sizeof(pbuf), "%d", RIP6_PORT); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; - hints.ai_socktype = SOCK_STREAM; + hints.ai_socktype = SOCK_DGRAM; error = getaddrinfo(argv[0], pbuf, &hints, &res); if (error) { - fprintf(stderr, "rip6query: %s: %s\n", argv[0], - gai_strerror(error)); - if (error == EAI_SYSTEM) - errx(1, "%s", strerror(errno)); - exit(1); + errx(1, "%s: %s", argv[0], gai_strerror(error)); /*NOTREACHED*/ } if (res->ai_next) { @@ -189,7 +185,7 @@ static const char * sa_n2a(sa) struct sockaddr *sa; { - static char buf[BUFSIZ]; + static char buf[NI_MAXHOST]; if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) != 0) { @@ -202,7 +198,7 @@ static const char * inet6_n2a(addr) struct in6_addr *addr; { - static char buf[BUFSIZ]; + static char buf[NI_MAXHOST]; return inet_ntop(AF_INET6, addr, buf, sizeof(buf)); } diff --git a/usr.sbin/route6d/Makefile b/usr.sbin/route6d/Makefile index 97b2d9d2554d0..02b1900dde557 100644 --- a/usr.sbin/route6d/Makefile +++ b/usr.sbin/route6d/Makefile @@ -4,6 +4,7 @@ PROG= route6d MAN8= route6d.8 -CFLAGS+= -Dss_len=__ss_len -Dss_family=__ss_family -DINET6 +CFLAGS+= -Dss_len=__ss_len -Dss_family=__ss_family -DINET6 \ + -DHAVE_GETIFADDRS .include <bsd.prog.mk> diff --git a/usr.sbin/route6d/route6d.8 b/usr.sbin/route6d/route6d.8 index 5ccd611e1e685..1457878f3696f 100644 --- a/usr.sbin/route6d/route6d.8 +++ b/usr.sbin/route6d/route6d.8 @@ -1,3 +1,6 @@ +.\" $FreeBSD$ +.\" $KAME: route6d.8,v 1.8 2000/05/31 17:00:09 itojun Exp $ +.\" .\" Copyright (c) 1996 WIDE Project. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -11,9 +14,6 @@ .\" 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 @@ -23,13 +23,27 @@ .Sh SYNOPSIS .Nm route6d .Op Fl adDhlqsS +.Bk -words .Op Fl R Ar routelog +.Ek +.Bk -words .Op Fl A Ar prefix/preflen,if1[,if2...] +.Ek +.Bk -words .Op Fl L Ar prefix/preflen,if1[,if2...] +.Ek +.Bk -words .Op Fl N Ar if1[,if2...] +.Ek +.Bk -words .Op Fl O Ar prefix/preflen,if1[,if2...] +.Ek +.Bk -words .Op Fl T Ar if1[,if2...] +.Ek +.Bk -words .Op Fl t Ar tag +.Ek .\" .Sh DESCRIPTION The @@ -92,7 +106,8 @@ Disables the split horizon processing. By default, .Nm will not exchange site local routes for safety reasons. -This is because semantics of site local address space is rather vague, +This is because semantics of site local address space is rather vague +.Pq specification is still in being worked , and there is no good way to define site local boundary. With .Fl l @@ -185,11 +200,11 @@ or .Dv SIGUSR1 , .Nm will dump the current internal state into -.Pa /var/tmp/route6d_dump . +.Pa /var/run/route6d_dump . .\" .Sh FILES -.Bl -tag -width /var/tmp/route6d_dump -compact -.It Pa /var/tmp/route6d_dump +.Bl -tag -width /var/run/route6d_dump -compact +.It Pa /var/run/route6d_dump dumps internal state on .Dv SIGINT or @@ -220,7 +235,7 @@ and .Li ff02::xx .Pc so they will be visible on internal state dump file -.Pq Pa /var/tmp/route6d_dump . +.Pq Pa /var/run/route6d_dump . .Pp Routing table manipulation differs from IPv6 implementation to implementation. Currently diff --git a/usr.sbin/route6d/route6d.c b/usr.sbin/route6d/route6d.c index 7097485d949c6..40788f6ffb161 100644 --- a/usr.sbin/route6d/route6d.c +++ b/usr.sbin/route6d/route6d.c @@ -1,11 +1,10 @@ -/* - * $Header: /cvsroot/kame/kame/kame/kame/route6d/route6d.c,v 1.6 1999/09/10 08:20:59 itojun Exp $ - */ +/* $FreeBSD$ */ +/* $KAME: route6d.c,v 1.30 2000/06/04 06:48:03 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: @@ -17,7 +16,7 @@ * 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 @@ -29,12 +28,10 @@ * 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$ */ #ifndef lint -static char _rcsid[] = "$Id: route6d.c,v 1.6 1999/09/10 08:20:59 itojun Exp $"; +static char _rcsid[] = "$KAME: route6d.c,v 1.30 2000/06/04 06:48:03 itojun Exp $"; #endif #include <stdio.h> @@ -51,6 +48,7 @@ static char _rcsid[] = "$Id: route6d.c,v 1.6 1999/09/10 08:20:59 itojun Exp $"; #endif #include <syslog.h> #include <stddef.h> +#include <errno.h> #include <err.h> #include <sys/types.h> @@ -59,16 +57,24 @@ static char _rcsid[] = "$Id: route6d.c,v 1.6 1999/09/10 08:20:59 itojun Exp $"; #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/sysctl.h> -#include <sys/errno.h> #include <sys/uio.h> #include <net/if.h> +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 #include <net/if_var.h> +#endif /* __FreeBSD__ >= 3 */ +#define KERNEL 1 +#define _KERNEL 1 #include <net/route.h> +#undef KERNEL +#undef _KERNEL #include <netinet/in.h> #include <netinet/in_var.h> #include <netinet/ip6.h> #include <netinet/udp.h> #include <netdb.h> +#ifdef HAVE_GETIFADDRS +#include <ifaddrs.h> +#endif #include <arpa/inet.h> @@ -83,9 +89,9 @@ static char _rcsid[] = "$Id: route6d.c,v 1.6 1999/09/10 08:20:59 itojun Exp $"; #endif /* alignment constraint for routing socket */ -#define ROUNDUP(a) \ +#define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) /* * Following two macros are highly depending on KAME Release @@ -113,7 +119,7 @@ struct ifc { /* Configuration of an interface */ int ifc_joined; /* joined to ff02::9 */ }; -struct ifac { /* Adddress associated to an interface */ +struct ifac { /* Adddress associated to an interface */ struct ifc *ifa_conf; /* back pointer */ struct ifac *ifa_next; struct in6_addr ifa_addr; /* address */ @@ -157,7 +163,8 @@ struct riprt { struct riprt *rrt_same; /* same destination - future use */ struct netinfo6 rrt_info; /* network info */ struct in6_addr rrt_gw; /* gateway */ - u_long rrt_flags; + u_long rrt_flags; /* kernel routing table flags */ + u_long rrt_rflags; /* route6d routing table flags */ time_t rrt_t; /* when the route validated */ int rrt_index; /* ifindex from which this route got */ }; @@ -172,7 +179,7 @@ int hflag = 0; /* don't split horizon */ int lflag = 0; /* exchange site local routes */ int sflag = 0; /* announce static routes w/ split horizon */ int Sflag = 0; /* announce static routes to every interface */ -int routetag = 0; /* route tag attached on originating case */ +unsigned long routetag = 0; /* route tag attached on originating case */ char *filter[MAXFILTER]; int filtertype[MAXFILTER]; @@ -194,14 +201,11 @@ int logopened = 0; static u_long seq = 0; -#define RTF_AGGREGATE 0x08000000 -#define RTF_NOADVERTISE 0x10000000 -#define RTF_NH_NOT_LLADDR 0x20000000 -#define RTF_SENDANYWAY 0x40000000 -#define RTF_CHANGED 0x80000000 -#define RTF_ROUTE_H 0xffff - -extern int errno; +#define RRTF_AGGREGATE 0x08000000 +#define RRTF_NOADVERTISE 0x10000000 +#define RRTF_NH_NOT_LLADDR 0x20000000 +#define RRTF_SENDANYWAY 0x40000000 +#define RRTF_CHANGED 0x80000000 int main __P((int, char **)); void ripalarm __P((int)); @@ -210,7 +214,7 @@ void ripsend __P((struct ifc *, struct sockaddr_in6 *, int)); void init __P((void)); void sockopt __P((struct ifc *)); void ifconfig __P((void)); -void ifconfig1 __P((struct ifreq *, struct ifc *, int)); +void ifconfig1 __P((const char *, const struct sockaddr *, struct ifc *, int)); void rtrecv __P((void)); int rt_del __P((const struct sockaddr_in6 *, const struct sockaddr_in6 *, const struct sockaddr_in6 *)); @@ -222,6 +226,7 @@ const char *rttypes __P((struct rt_msghdr *rtm)); const char *rtflags __P((struct rt_msghdr *rtm)); const char *ifflags __P((int flags)); void ifrt __P((struct ifc *, int)); +void ifrt_p2p __P((struct ifc *, int)); void applymask __P((struct in6_addr *, struct in6_addr *)); void applyplen __P((struct in6_addr *, int)); void ifrtdump __P((int)); @@ -268,9 +273,8 @@ main(argc, argv) struct ifc *ifcp; sigset_t mask, omask; FILE *pidfile; - extern char *optarg; - extern int optind; char *progname; + char *ep; progname = strrchr(*argv, '/'); if (progname) @@ -286,35 +290,41 @@ main(argc, argv) case 'O': case 'T': case 'L': - if (nfilter >= MAXFILTER) + if (nfilter >= MAXFILTER) { fatal("Exceeds MAXFILTER"); + /*NOTREACHED*/ + } filtertype[nfilter] = ch; filter[nfilter++] = allocopy(optarg); break; case 't': - sscanf(optarg, "%i", &routetag); - if (routetag & ~0xffff) { + ep = NULL; + routetag = strtoul(optarg, &ep, 0); + if (!ep || *ep != '\0' || (routetag & ~0xffff) != 0) { fatal("invalid route tag"); /*NOTREACHED*/ } break; case 'R': - if ((rtlog = fopen(optarg, "w")) == NULL) + if ((rtlog = fopen(optarg, "w")) == NULL) { fatal("Can not write to routelog"); + /*NOTREACHED*/ + } break; -#define FLAG(c, flag, n) case c: flag = n; break - FLAG('a', aflag, 1); - FLAG('d', dflag, 1); - FLAG('D', dflag, 2); - FLAG('h', hflag, 1); - FLAG('l', lflag, 1); - FLAG('n', nflag, 1); - FLAG('q', qflag, 1); - FLAG('s', sflag, 1); - FLAG('S', Sflag, 1); +#define FLAG(c, flag, n) case c: do { flag = n; break; } while(0) + FLAG('a', aflag, 1); break; + FLAG('d', dflag, 1); break; + FLAG('D', dflag, 2); break; + FLAG('h', hflag, 1); break; + FLAG('l', lflag, 1); break; + FLAG('n', nflag, 1); break; + FLAG('q', qflag, 1); break; + FLAG('s', sflag, 1); break; + FLAG('S', Sflag, 1); break; #undef FLAG default: fatal("Invalid option specified, terminating"); + /*NOTREACHED*/ } } argc -= optind; @@ -351,8 +361,15 @@ main(argc, argv) ifrtdump(0); if (dflag == 0) { +#if 1 if (daemon(0, 0) < 0) fatal("daemon"); +#else + if (fork()) + exit(0); + if (setsid() < 0) + fatal("setid"); +#endif } pid = getpid(); if ((pidfile = fopen(ROUTE6D_PID, "w")) != NULL) { @@ -362,6 +379,7 @@ main(argc, argv) if ((ripbuf = (struct rip6 *)malloc(RIP6_MAXMTU)) == NULL) fatal("malloc"); + memset(ripbuf, 0, RIP6_MAXMTU); ripbuf->rip6_cmd = RIP6_RESPONSE; ripbuf->rip6_vers = RIP6_VERSION; ripbuf->rip6_res1[0] = 0; @@ -432,7 +450,7 @@ rtdexit(sig) alarm(0); for (rrt = riprt; rrt; rrt = rrt->rrt_next) { - if (rrt->rrt_flags & RTF_AGGREGATE) { + if (rrt->rrt_rflags & RRTF_AGGREGATE) { delroute(&rrt->rrt_info, &rrt->rrt_gw); } } @@ -496,8 +514,7 @@ ripalarm(sig) void init() { - int i; - int int0, int255, error; + int i, int0, int255, error; struct addrinfo hints, *res; char port[10]; @@ -529,9 +546,17 @@ init() if (setsockopt(ripsock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &int0, sizeof(int0)) < 0) fatal("rip IPV6_MULTICAST_LOOP"); + i = 1; - if (setsockopt(ripsock, IPPROTO_IPV6, IPV6_PKTINFO, &i, sizeof(i)) < 0) +#ifdef IPV6_RECVPKTINFO + if (setsockopt(ripsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &i, + sizeof(i)) < 0) + fatal("rip IPV6_RECVPKTINFO"); +#else /* old adv. API */ + if (setsockopt(ripsock, IPPROTO_IPV6, IPV6_PKTINFO, &i, + sizeof(i)) < 0) fatal("rip IPV6_PKTINFO"); +#endif memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_INET6; @@ -558,7 +583,8 @@ init() rtsock = -1; /*just for safety */ } -#define RIPSIZE(n) (sizeof(struct rip6) + (n-1) * sizeof(struct netinfo6)) +#define RIPSIZE(n) \ + (sizeof(struct rip6) + ((n)-1) * sizeof(struct netinfo6)) /* * ripflush flushes the rip datagram stored in the rip buffer @@ -586,7 +612,7 @@ ripflush(ifcp, sin) for (i = 0; i < nrt; i++, np++) { if (np->rip6_metric == NEXTHOP_METRIC) { if (IN6_IS_ADDR_UNSPECIFIED(&np->rip6_dest)) - trace(2, " NextHop reset"); + trace(2, " NextHop reset"); else { trace(2, " NextHop %s", inet6_n2p(&np->rip6_dest)); @@ -634,13 +660,13 @@ ripsend(ifcp, sin, flag) * Request from non-link local address is not * a regular route6d update. */ - maxrte = (IFMINMTU - sizeof(struct ip6_hdr) - - sizeof(struct udphdr) - + maxrte = (IFMINMTU - sizeof(struct ip6_hdr) - + sizeof(struct udphdr) - sizeof(struct rip6) + sizeof(struct netinfo6)) / sizeof(struct netinfo6); nrt = 0; np = ripbuf->rip6_nets; nh = NULL; for (rrt = riprt; rrt; rrt = rrt->rrt_next) { - if (rrt->rrt_flags & RTF_NOADVERTISE) + if (rrt->rrt_rflags & RRTF_NOADVERTISE) continue; /* Put the route to the buffer */ *np = rrt->rrt_info; @@ -655,7 +681,7 @@ ripsend(ifcp, sin, flag) return; } - if ((flag & RTF_SENDANYWAY) == 0 && + if ((flag & RRTF_SENDANYWAY) == 0 && (qflag || (ifcp->ifc_flags & IFF_LOOPBACK))) return; if (iff_find(ifcp, 'N') != NULL) @@ -673,13 +699,13 @@ ripsend(ifcp, sin, flag) ripflush(ifcp, sin); return; } - maxrte = (ifcp->ifc_mtu - sizeof(struct ip6_hdr) - - sizeof(struct udphdr) - + maxrte = (ifcp->ifc_mtu - sizeof(struct ip6_hdr) - + sizeof(struct udphdr) - sizeof(struct rip6) + sizeof(struct netinfo6)) / sizeof(struct netinfo6); nrt = 0; np = ripbuf->rip6_nets; nh = NULL; for (rrt = riprt; rrt; rrt = rrt->rrt_next) { - if (rrt->rrt_flags & RTF_NOADVERTISE) + if (rrt->rrt_rflags & RRTF_NOADVERTISE) continue; /* Need to check filer here */ ok = 1; @@ -688,7 +714,7 @@ ripsend(ifcp, sin, flag) continue; if (rrt->rrt_info.rip6_plen <= iffp->iff_plen) continue; - ia = rrt->rrt_info.rip6_dest; + ia = rrt->rrt_info.rip6_dest; applyplen(&ia, iffp->iff_plen); if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) { ok = 0; @@ -703,7 +729,7 @@ ripsend(ifcp, sin, flag) ok = 0; if (rrt->rrt_info.rip6_plen < iffp->iff_plen) continue; - ia = rrt->rrt_info.rip6_dest; + ia = rrt->rrt_info.rip6_dest; applyplen(&ia, iffp->iff_plen); if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) { ok = 1; @@ -716,12 +742,13 @@ ripsend(ifcp, sin, flag) if (tobeadv(rrt, ifcp) == 0) continue; /* Only considers the routes with flag if specified */ - if ((flag & RTF_CHANGED) && (rrt->rrt_flags & RTF_CHANGED) == 0) + if ((flag & RRTF_CHANGED) && + (rrt->rrt_rflags & RRTF_CHANGED) == 0) continue; /* Check nexthop */ if (rrt->rrt_index == ifcp->ifc_index && !IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_gw) && - (rrt->rrt_flags & RTF_NH_NOT_LLADDR) == 0) { + (rrt->rrt_rflags & RRTF_NH_NOT_LLADDR) == 0) { if (nh == NULL || !IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw)) { if (nrt == maxrte - 2) ripflush(ifcp, sin); @@ -736,7 +763,7 @@ ripsend(ifcp, sin, flag) } } else if (nh && (rrt->rrt_index != ifcp->ifc_index || !IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw) || - rrt->rrt_flags & RTF_NH_NOT_LLADDR)) { + rrt->rrt_rflags & RRTF_NH_NOT_LLADDR)) { /* Reset nexthop */ if (nrt == maxrte - 2) ripflush(ifcp, sin); @@ -769,6 +796,10 @@ tobeadv(rrt, ifcp) /* Special care for static routes */ if (rrt->rrt_flags & RTF_STATIC) { + /* XXX don't advertise reject/blackhole routes */ + if (rrt->rrt_flags & (RTF_REJECT | RTF_BLACKHOLE)) + return 0; + if (Sflag) /* Yes, advertise it anyway */ return 1; if (sflag && rrt->rrt_index != ifcp->ifc_index) @@ -840,6 +871,7 @@ sendpacket(sin, len) trace(1, "sendmsg: %s\n", strerror(errno)); return errno; } + return 0; } @@ -869,6 +901,7 @@ riprecv() int ok; need_trigger = 0; + m.msg_name = (caddr_t)&fsock; m.msg_namelen = sizeof(fsock); iov[0].iov_base = (caddr_t)buf; @@ -911,8 +944,8 @@ riprecv() } else { riprequest(NULL, np, nn, &fsock); } - return; - } + return; + } if (!IN6_IS_ADDR_LINKLOCAL(&fsock.sin6_addr)) { trace(1, "Packets from non-ll addr: %s\n", @@ -929,7 +962,7 @@ riprecv() return; /* The packet is from me; ignore */ if (rp->rip6_cmd != RIP6_RESPONSE) { trace(1, "Invalid command %d\n", rp->rip6_cmd); - return; + return; } if (iff_find(ifcp, 'N') != NULL) return; @@ -984,6 +1017,12 @@ riprecv() np->rip6_plen, np->rip6_metric); if (np->rip6_tag) trace(2, " tag=0x%04x", ntohs(np->rip6_tag) & 0xffff); + if (dflag >= 2) { + ia = np->rip6_dest; + applyplen(&ia, np->rip6_plen); + if (!IN6_ARE_ADDR_EQUAL(&ia, &np->rip6_dest)) + trace(2, " [junk outside prefix]"); + } /* Listen-only filter */ ok = 1; /* if there's no L filter, it is ok */ @@ -996,7 +1035,7 @@ riprecv() /* special rule: ::/0 means default, not "in /0" */ if (iffp->iff_plen == 0 && np->rip6_plen > 0) continue; - ia = np->rip6_dest; + ia = np->rip6_dest; applyplen(&ia, iffp->iff_plen); if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) { ok = 1; @@ -1033,7 +1072,7 @@ riprecv() *nq = *np; addroute(rrt, &nh, ifcp); } - rrt->rrt_flags |= RTF_CHANGED; + rrt->rrt_rflags |= RRTF_CHANGED; rrt->rrt_t = t; need_trigger = 1; } else if (nq->rip6_metric < np->rip6_metric && @@ -1042,7 +1081,7 @@ riprecv() /* Got worse route from same gw */ nq->rip6_metric = np->rip6_metric; rrt->rrt_t = t; - rrt->rrt_flags |= RTF_CHANGED; + rrt->rrt_rflags |= RRTF_CHANGED; need_trigger = 1; } else if (nq->rip6_metric == np->rip6_metric && rrt->rrt_index == ifcp->ifc_index && @@ -1051,7 +1090,7 @@ riprecv() /* same metric, same route from same gw */ rrt->rrt_t = t; } - /* + /* * if nq->rip6_metric == HOPCNT_INFINITY6 then * do not update age value. Do nothing. */ @@ -1059,6 +1098,7 @@ riprecv() /* Got a new valid route */ if ((rrt = MALLOC(struct riprt)) == NULL) fatal("malloc: struct riprt"); + memset(rrt, 0, sizeof(*rrt)); nq = &rrt->rrt_info; rrt->rrt_same = NULL; @@ -1075,7 +1115,7 @@ riprecv() riprt = rrt; /* Update routing table */ addroute(rrt, &nh, ifcp); - rrt->rrt_flags |= RTF_CHANGED; + rrt->rrt_rflags |= RRTF_CHANGED; need_trigger = 1; rrt->rrt_t = t; } @@ -1088,12 +1128,12 @@ riprecv() continue; if (ic->ifc_flags & IFF_UP) ripsend(ic, &ic->ifc_ripsin, - RTF_CHANGED); + RRTF_CHANGED); } } /* Reset the flag */ for (rrt = riprt; rrt; rrt = rrt->rrt_next) - rrt->rrt_flags &= ~RTF_CHANGED; + rrt->rrt_rflags &= ~RRTF_CHANGED; } } @@ -1155,7 +1195,7 @@ riprequest(ifcp, np, nn, sin) } /* Whole routing table dump */ trace(1, "\tRIP Request -- whole routing table\n"); - ripsend(ifcp, sin, RTF_SENDANYWAY); + ripsend(ifcp, sin, RRTF_SENDANYWAY); } /* @@ -1164,6 +1204,66 @@ riprequest(ifcp, np, nn, sin) void ifconfig() { +#ifdef HAVE_GETIFADDRS + struct ifaddrs *ifap, *ifa; + struct ifc *ifcp; + struct ipv6_mreq mreq; + int s; + + if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + fatal("socket"); + + if (getifaddrs(&ifap) != 0) + fatal("getifaddrs"); + + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + ifcp = ifc_find(ifa->ifa_name); + /* we are interested in multicast-capable interfaces */ + if ((ifa->ifa_flags & IFF_MULTICAST) == 0) + continue; + if (!ifcp) { + /* new interface */ + if ((ifcp = MALLOC(struct ifc)) == NULL) + fatal("malloc: struct ifc"); + memset(ifcp, 0, sizeof(*ifcp)); + ifcp->ifc_index = -1; + ifcp->ifc_next = ifc; + ifc = ifcp; + nifc++; + ifcp->ifc_name = allocopy(ifa->ifa_name); + ifcp->ifc_addr = 0; + ifcp->ifc_filter = 0; + ifcp->ifc_flags = ifa->ifa_flags; + trace(1, "newif %s <%s>\n", ifcp->ifc_name, + ifflags(ifcp->ifc_flags)); + if (!strcmp(ifcp->ifc_name, LOOPBACK_IF)) + loopifcp = ifcp; + } else { + /* update flag, this may be up again */ + if (ifcp->ifc_flags != ifa->ifa_flags) { + trace(1, "%s: <%s> -> ", ifcp->ifc_name, + ifflags(ifcp->ifc_flags)); + trace(1, "<%s>\n", ifflags(ifa->ifa_flags)); + } + ifcp->ifc_flags = ifa->ifa_flags; + } + ifconfig1(ifa->ifa_name, ifa->ifa_addr, ifcp, s); + if ((ifcp->ifc_flags & (IFF_LOOPBACK | IFF_UP)) == IFF_UP + && 0 < ifcp->ifc_index && !ifcp->ifc_joined) { + mreq.ipv6mr_multiaddr = ifcp->ifc_ripsin.sin6_addr; + mreq.ipv6mr_interface = ifcp->ifc_index; + if (setsockopt(ripsock, IPPROTO_IPV6, + IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) < 0) + fatal("IPV6_JOIN_GROUP"); + trace(1, "join %s %s\n", ifcp->ifc_name, RIP6_DEST); + ifcp->ifc_joined++; + } + } + close(s); + freeifaddrs(ifap); +#else int s, i; char *buf; struct ifconf ifconf; @@ -1191,6 +1291,8 @@ ifconfig() fatal("ioctl: SIOCGIFCONF"); i = ifconf.ifc_len; while (1) { + char *newbuf; + ifconf.ifc_buf = buf; ifconf.ifc_len = bufsiz; if (ioctl(s, SIOCGIFCONF, (char *)&ifconf) < 0) @@ -1199,8 +1301,11 @@ ifconfig() break; i = ifconf.ifc_len; bufsiz *= 2; - if ((buf = (char *)realloc(buf, bufsiz)) == NULL) + if ((newbuf = (char *)realloc(buf, bufsiz)) == NULL) { + free(buf); fatal("realloc"); + } + buf = newbuf; } for (i = 0; i < ifconf.ifc_len; ) { ifrp = (struct ifreq *)(buf + i); @@ -1215,7 +1320,8 @@ ifconfig() goto skip; if (!ifcp) { /* new interface */ - ifcp = (struct ifc *)malloc(sizeof(*ifcp)); + if ((ifcp = MALLOC(struct ifc)) == NULL) + fatal("malloc: struct ifc"); memset(ifcp, 0, sizeof(*ifcp)); ifcp->ifc_index = -1; ifcp->ifc_next = ifc; @@ -1238,7 +1344,7 @@ ifconfig() } ifcp->ifc_flags = ifr.ifr_flags; } - ifconfig1(ifrp, ifcp, s); + ifconfig1(ifrp->ifr_name, &ifrp->ifr_addr, ifcp, s); if ((ifcp->ifc_flags & (IFF_LOOPBACK | IFF_UP)) == IFF_UP && 0 < ifcp->ifc_index && !ifcp->ifc_joined) { mreq.ipv6mr_multiaddr = ifcp->ifc_ripsin.sin6_addr; @@ -1258,11 +1364,13 @@ skip: } close(s); free(buf); +#endif } void -ifconfig1(ifrp, ifcp, s) - struct ifreq *ifrp; +ifconfig1(name, sa, ifcp, s) + const char *name; + const struct sockaddr *sa; struct ifc *ifcp; int s; { @@ -1272,9 +1380,9 @@ ifconfig1(ifrp, ifcp, s) int plen; char buf[BUFSIZ]; - sin = (struct sockaddr_in6 *)&ifrp->ifr_addr; + sin = (struct sockaddr_in6 *)sa; ifr.ifr_addr = *sin; - strcpy(ifr.ifr_name, ifrp->ifr_name); + strcpy(ifr.ifr_name, name); if (ioctl(s, SIOCGIFNETMASK_IN6, (char *)&ifr) < 0) fatal("ioctl: SIOCGIFNETMASK_IN6"); plen = mask2len(&ifr.ifr_addr.sin6_addr, 16); @@ -1289,6 +1397,7 @@ ifconfig1(ifrp, ifcp, s) */ if ((ifa = MALLOC(struct ifac)) == NULL) fatal("malloc: struct ifac"); + memset(ifa, 0, sizeof(*ifa)); ifa->ifa_conf = ifcp; ifa->ifa_next = ifcp->ifc_addr; ifcp->ifc_addr = ifa; @@ -1440,7 +1549,7 @@ rtrecv() #if 0 if (rta[RTAX_DST] == NULL) { trace(1, "\tno destination, ignored\n"); - continue; + continue; } if (rta[RTAX_DST]->sin6_family != AF_INET6) { trace(1, "\taf mismatch, ignored\n"); @@ -1586,7 +1695,7 @@ rt_del(sdst, sgw, smask) gw = &in6addr_loopback; prefix = rrt->rrt_info.rip6_plen; } else { - trace(1, "\tunsupported af: (gw=%d, mask=%d)\n", + trace(1, "\tunsupported af: (gw=%d, mask=%d)\n", sgw->sin6_family, smask->sin6_family); return -1; } @@ -1738,20 +1847,39 @@ rt_deladdr(ifcp, sifa, smask) */ void ifrt(ifcp, again) - struct ifc *ifcp; + struct ifc *ifcp; int again; { - struct ifac *ifa; - struct riprt *rrt; - struct netinfo6 *np; + struct ifac *ifa; + struct riprt *rrt; + struct netinfo6 *np; if (ifcp->ifc_flags & IFF_LOOPBACK) return; /* ignore loopback */ + if (ifcp->ifc_flags & IFF_POINTOPOINT) { + ifrt_p2p(ifcp, again); + return; + } + for (ifa = ifcp->ifc_addr; ifa; ifa = ifa->ifa_next) { - if (IN6_IS_ADDR_LINKLOCAL(&ifa->ifa_addr)) - continue; /* don't advertise link local addr */ + if (IN6_IS_ADDR_LINKLOCAL(&ifa->ifa_addr)) { +#if 0 + trace(1, "route: %s on %s: " + "skip linklocal interface address\n", + inet6_n2p(&ifa->ifa_addr), ifcp->ifc_name); +#endif + continue; + } + if (IN6_IS_ADDR_UNSPECIFIED(&ifa->ifa_addr)) { +#if 0 + trace(1, "route: %s: skip unspec interface address\n", + ifcp->ifc_name); +#endif + continue; + } if ((rrt = MALLOC(struct riprt)) == NULL) fatal("malloc: struct riprt"); + memset(rrt, 0, sizeof(*rrt)); rrt->rrt_same = NULL; rrt->rrt_index = ifcp->ifc_index; rrt->rrt_t = 0; /* don't age */ @@ -1764,46 +1892,162 @@ ifrt(ifcp, again) np = &rrt->rrt_info; if (rtsearch(np) == NULL) { /* Attach the route to the list */ + trace(1, "route: %s/%d: register route (%s)\n", + inet6_n2p(&np->rip6_dest), np->rip6_plen, + ifcp->ifc_name); rrt->rrt_next = riprt; riprt = rrt; } else { /* Already found */ if (!again) { - trace(1, "route: %s/%d: already registered\n", - inet6_n2p(&np->rip6_dest), - np->rip6_plen); + trace(1, "route: %s/%d: " + "already registered (%s)\n", + inet6_n2p(&np->rip6_dest), np->rip6_plen, + ifcp->ifc_name); } free(rrt); } + } +} - if (ifcp->ifc_flags & IFF_POINTOPOINT) { +/* + * there are couple of p2p interface routing models. "behavior" lets + * you pick one. it looks that gated behavior fits best with BSDs, + * since BSD kernels does not look at prefix length on p2p interfaces. + */ +void +ifrt_p2p(ifcp, again) + struct ifc *ifcp; + int again; +{ + struct ifac *ifa; + struct riprt *rrt; + struct netinfo6 *np; + struct in6_addr addr, dest; + int advert, ignore, i; +#define P2PADVERT_NETWORK 1 +#define P2PADVERT_ADDR 2 +#define P2PADVERT_DEST 4 +#define P2PADVERT_MAX 4 + const enum { CISCO, GATED, ROUTE6D } behavior = GATED; + const char *category; + const char *noadv; + + for (ifa = ifcp->ifc_addr; ifa; ifa = ifa->ifa_next) { + addr = ifa->ifa_addr; + dest = ifa->ifa_raddr; + applyplen(&addr, ifa->ifa_plen); + applyplen(&dest, ifa->ifa_plen); + advert = ignore = 0; + switch (behavior) { + case CISCO: + /* + * honor addr/plen, just like normal shared medium + * interface. this may cause trouble if you reuse + * addr/plen on other interfaces. + * + * advertise addr/plen. + */ + advert |= P2PADVERT_NETWORK; + break; + case GATED: + /* + * prefixlen on p2p interface is meaningless. + * advertise addr/128 and dest/128. + * + * do not install network route to route6d routing + * table (if we do, it would prevent route installation + * for other p2p interface that shares addr/plen). + */ + advert |= P2PADVERT_ADDR; + advert |= P2PADVERT_DEST; + ignore |= P2PADVERT_NETWORK; + break; + case ROUTE6D: + /* + * just for testing... + */ + if (IN6_ARE_ADDR_EQUAL(&addr, &dest)) + advert |= P2PADVERT_NETWORK; + else { + advert |= P2PADVERT_ADDR; + advert |= P2PADVERT_DEST; + ignore |= P2PADVERT_NETWORK; + } + break; + } + + for (i = 1; i <= P2PADVERT_MAX; i *= 2) { + if ((ignore & i) != 0) + continue; if ((rrt = MALLOC(struct riprt)) == NULL) fatal("malloc: struct riprt"); + memset(rrt, 0, sizeof(*rrt)); rrt->rrt_same = NULL; rrt->rrt_index = ifcp->ifc_index; - rrt->rrt_t = 0; /* Don't age */ - rrt->rrt_info.rip6_dest = ifa->ifa_raddr; + rrt->rrt_t = 0; /* don't age */ + switch (i) { + case P2PADVERT_NETWORK: + rrt->rrt_info.rip6_dest = ifa->ifa_addr; + rrt->rrt_info.rip6_plen = ifa->ifa_plen; + applyplen(&rrt->rrt_info.rip6_dest, + ifa->ifa_plen); + category = "network"; + break; + case P2PADVERT_ADDR: + rrt->rrt_info.rip6_dest = ifa->ifa_addr; + rrt->rrt_info.rip6_plen = 128; + category = "addr"; + break; + case P2PADVERT_DEST: + rrt->rrt_info.rip6_dest = ifa->ifa_raddr; + rrt->rrt_info.rip6_plen = 128; + category = "dest"; + break; + } + if (IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_info.rip6_dest) || + IN6_IS_ADDR_LINKLOCAL(&rrt->rrt_info.rip6_dest)) { +#if 0 + trace(1, "route: %s: skip unspec/linklocal " + "(%s on %s)\n", category, ifcp->ifc_name); +#endif + free(rrt); + continue; + } + if ((advert & i) == 0) { + rrt->rrt_rflags |= RRTF_NOADVERTISE; + noadv = ", NO-ADV"; + } else + noadv = ""; rrt->rrt_info.rip6_tag = htons(routetag & 0xffff); - rrt->rrt_info.rip6_metric = 1; - rrt->rrt_info.rip6_plen = 128; - rrt->rrt_gw = ifa->ifa_addr; - rrt->rrt_flags |= RTF_NOADVERTISE; + rrt->rrt_info.rip6_metric = 1 + ifcp->ifc_metric; + memset(&rrt->rrt_gw, 0, sizeof(struct in6_addr)); np = &rrt->rrt_info; if (rtsearch(np) == NULL) { /* Attach the route to the list */ + trace(1, "route: %s/%d: register route " + "(%s on %s%s)\n", + inet6_n2p(&np->rip6_dest), np->rip6_plen, + category, ifcp->ifc_name, noadv); rrt->rrt_next = riprt; riprt = rrt; } else { /* Already found */ if (!again) { - trace(1, "route: %s/%d: already registered\n", - inet6_n2p(&np->rip6_dest), - np->rip6_plen); + trace(1, "route: %s/%d: " + "already registered (%s on %s%s)\n", + inet6_n2p(&np->rip6_dest), + np->rip6_plen, category, + ifcp->ifc_name, noadv); } free(rrt); } } } +#undef P2PADVERT_NETWORK +#undef P2PADVERT_ADDR +#undef P2PADVERT_DEST +#undef P2PADVERT_MAX } int @@ -1842,7 +2086,11 @@ const char * rttypes(rtm) struct rt_msghdr *rtm; { -#define RTTYPE(s, f) if (rtm->rtm_type == (f)) return (s) +#define RTTYPE(s, f) \ +do { \ + if (rtm->rtm_type == (f)) \ + return (s); \ +} while (0) RTTYPE("ADD", RTM_ADD); RTTYPE("DELETE", RTM_DELETE); RTTYPE("CHANGE", RTM_CHANGE); @@ -1868,7 +2116,11 @@ rtflags(rtm) static char buf[BUFSIZ]; strcpy(buf, ""); -#define RTFLAG(s, f) if (rtm->rtm_flags & (f)) strcat(buf, (s)) +#define RTFLAG(s, f) \ +do { \ + if (rtm->rtm_flags & (f)) \ + strcat(buf, (s)); \ +} while (0) RTFLAG("U", RTF_UP); RTFLAG("G", RTF_GATEWAY); RTFLAG("H", RTF_HOST); @@ -1897,8 +2149,14 @@ ifflags(flags) static char buf[BUFSIZ]; strcpy(buf, ""); -#define IFFLAG(s, f) \ - if (flags & f) { if (buf[0]) strcat(buf, ","); strcat(buf, s); } +#define IFFLAG(s, f) \ +do { \ + if (flags & f) { \ + if (buf[0]) \ + strcat(buf, ","); \ + strcat(buf, s); \ + } \ +} while (0) IFFLAG("UP", IFF_UP); IFFLAG("BROADCAST", IFF_BROADCAST); IFFLAG("DEBUG", IFF_DEBUG); @@ -1979,15 +2237,15 @@ rt_entry(rtm, again) struct sockaddr_in6 *sin6_dst, *sin6_gw, *sin6_mask; struct sockaddr_in6 *sin6_genmask, *sin6_ifp; char *rtmp, *ifname = NULL; - char buf[BUFSIZ]; struct riprt *rrt; struct netinfo6 *np; int s; sin6_dst = sin6_gw = sin6_mask = sin6_genmask = sin6_ifp = 0; if ((rtm->rtm_flags & RTF_UP) == 0 || rtm->rtm_flags & - (RTF_CLONING|RTF_XRESOLVE|RTF_LLINFO|RTF_BLACKHOLE)) + (RTF_CLONING|RTF_XRESOLVE|RTF_LLINFO|RTF_BLACKHOLE)) { return; /* not interested in the link route */ + } rtmp = (char *)(rtm + 1); /* Destination */ if ((rtm->rtm_addrs & RTA_DST) == 0) @@ -2023,6 +2281,7 @@ rt_entry(rtm, again) if ((rrt = MALLOC(struct riprt)) == NULL) fatal("malloc: struct riprt"); + memset(rrt, 0, sizeof(*rrt)); np = &rrt->rrt_info; rrt->rrt_same = NULL; rrt->rrt_t = time(NULL); @@ -2080,11 +2339,14 @@ rt_entry(rtm, again) ifname = index2ifc[s]->ifc_name; else { trace(1, " not configured\n"); + free(rrt); return; } - trace(1, " if %s sock %d\n", ifname, s); + trace(1, " if %s sock %d", ifname, s); rrt->rrt_index = s; + trace(1, "\n"); + /* Check gateway */ if (!IN6_IS_ADDR_LINKLOCAL(&rrt->rrt_gw) && !IN6_IS_ADDR_LOOPBACK(&rrt->rrt_gw) @@ -2092,13 +2354,11 @@ rt_entry(rtm, again) && (rrt->rrt_flags & RTF_LOCAL) == 0 #endif ) { - inet_ntop(AF_INET6, (void *)&rrt->rrt_info.rip6_dest, - buf, sizeof(buf)); trace(0, "***** Gateway %s is not a link-local address.\n", inet6_n2p(&rrt->rrt_gw)); trace(0, "***** dest(%s) if(%s) -- Not optimized.\n", - buf, ifname); - rrt->rrt_flags |= RTF_NH_NOT_LLADDR; + inet6_n2p(&rrt->rrt_info.rip6_dest), ifname); + rrt->rrt_rflags |= RRTF_NH_NOT_LLADDR; } /* Put it to the route list */ @@ -2137,7 +2397,7 @@ addroute(rrt, gw, ifcp) rtm->rtm_version = RTM_VERSION; rtm->rtm_seq = ++seq; rtm->rtm_pid = pid; - rtm->rtm_flags = rrt->rrt_flags & RTF_ROUTE_H; + rtm->rtm_flags = rrt->rrt_flags; rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; rtm->rtm_rmx.rmx_hopcount = np->rip6_metric - 1; rtm->rtm_inits = RTV_HOPCOUNT; @@ -2439,9 +2699,9 @@ rtdump(sig) fprintf(dump, " tag(0x%04x)", ntohs(rrt->rrt_info.rip6_tag) & 0xffff); } - if (rrt->rrt_flags & RTF_NH_NOT_LLADDR) + if (rrt->rrt_rflags & RRTF_NH_NOT_LLADDR) fprintf(dump, " NOT-LL"); - if (rrt->rrt_flags & RTF_NOADVERTISE) + if (rrt->rrt_rflags & RRTF_NOADVERTISE) fprintf(dump, " NO-ADV"); fprintf(dump, "\n"); } @@ -2519,7 +2779,8 @@ ifonly: rrt->rrt_info.rip6_metric = 1; rrt->rrt_info.rip6_tag = htons(routetag & 0xffff); rrt->rrt_gw = in6addr_loopback; - rrt->rrt_flags = RTF_UP | RTF_REJECT | RTF_AGGREGATE; + rrt->rrt_flags = RTF_UP | RTF_REJECT; + rrt->rrt_rflags = RRTF_AGGREGATE; rrt->rrt_t = 0; rrt->rrt_index = loopifindex; /* Put the route to the list */ @@ -2534,7 +2795,7 @@ ifonly: if (getroute(&rrt->rrt_info, &gw)) { /* * When the address has already been registered in the - * kernel routing table, it should be removed + * kernel routing table, it should be removed */ delroute(&rrt->rrt_info, &gw); } @@ -2592,7 +2853,7 @@ mask2len(addr, lenlim) { int i = 0, j; u_char *p = (u_char *)addr; - + for (j = 0; j < lenlim; j++, p++) { if (*p != 0xff) break; @@ -2600,14 +2861,14 @@ mask2len(addr, lenlim) } if (j < lenlim) { switch (*p) { -#define MASKLEN(m, l) case m: i += l; break - MASKLEN(0xfe, 7); - MASKLEN(0xfc, 6); - MASKLEN(0xf8, 5); - MASKLEN(0xf0, 4); - MASKLEN(0xe0, 3); - MASKLEN(0xc0, 2); - MASKLEN(0x80, 1); +#define MASKLEN(m, l) case m: do { i += l; break; } while (0) + MASKLEN(0xfe, 7); break; + MASKLEN(0xfc, 6); break; + MASKLEN(0xf8, 5); break; + MASKLEN(0xf0, 4); break; + MASKLEN(0xe0, 3); break; + MASKLEN(0xc0, 2); break; + MASKLEN(0x80, 1); break; #undef MASKLEN } } @@ -2716,7 +2977,7 @@ ripsuptrig() time_t t; double r = rand(); - t = (int)(RIP_TRIG_INT6_MIN + + t = (int)(RIP_TRIG_INT6_MIN + (RIP_TRIG_INT6_MAX - RIP_TRIG_INT6_MIN) * (r / RAND_MAX )); sup_trig_update = time(NULL) + t; return t; @@ -2852,6 +3113,7 @@ setindex2ifc(index, ifcp) struct ifc *ifcp; { int n; + struct ifc **p; if (!index2ifc) { nindex2ifc = 5; /*initial guess*/ @@ -2865,10 +3127,11 @@ setindex2ifc(index, ifcp) while (nindex2ifc <= index) nindex2ifc *= 2; if (n != nindex2ifc) { - index2ifc = (struct ifc **) - realloc(index2ifc, sizeof(*index2ifc) * nindex2ifc); - if (index2ifc == NULL) + p = (struct ifc **)realloc(index2ifc, + sizeof(*index2ifc) * nindex2ifc); + if (p == NULL) fatal("realloc"); + index2ifc = p; } index2ifc[index] = ifcp; } diff --git a/usr.sbin/route6d/route6d.h b/usr.sbin/route6d/route6d.h index 7808c04fbdb88..b3a353f59e728 100644 --- a/usr.sbin/route6d/route6d.h +++ b/usr.sbin/route6d/route6d.h @@ -1,11 +1,10 @@ -/* - * $Header: /cvsroot/kame/kame/kame/kame/route6d/route6d.h,v 1.1.1.1 1999/08/08 23:31:35 itojun Exp $ - */ +/* $FreeBSD$ */ +/* $KAME: route6d.h,v 1.3 2000/02/25 06:15:06 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: @@ -17,7 +16,7 @@ * 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 @@ -29,15 +28,13 @@ * 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 +/* not yet in use #define ROUTE6D_CONF "/usr/local/v6/etc/route6d.conf" */ -#define ROUTE6D_DUMP "/var/tmp/route6d_dump" +#define ROUTE6D_DUMP "/var/run/route6d_dump" #define ROUTE6D_PID "/var/run/route6d.pid" #define RIP6_VERSION 1 diff --git a/usr.sbin/rrenumd/Makefile b/usr.sbin/rrenumd/Makefile index 990ddab13a6bf..42a0195e9eadf 100644 --- a/usr.sbin/rrenumd/Makefile +++ b/usr.sbin/rrenumd/Makefile @@ -17,13 +17,9 @@ PROG= rrenumd SRCS= rrenumd.c parser.y lexer.l YFLAGS+= -d -CC= gcc - CFLAGS+= -DINET6 -DIPSEC -I${.OBJDIR} -LDADD+= -lipsec -lcompat -DPADD+= ${LIBIPSEC} ${LIBCOMPAT} -LDADD+= -ll -ly -DPADD+= ${LIBL} ${LIBY} +LDADD= -lipsec -lcompat -ll -ly +DPADD= ${LIBIPSEC} ${LIBCOMPAT} ${LIBL} ${LIBY} MAN5= rrenumd.conf.5 MAN8= rrenumd.8 diff --git a/usr.sbin/rrenumd/lexer.l b/usr.sbin/rrenumd/lexer.l index 80429af3b4a61..d906b0c6acf9b 100644 --- a/usr.sbin/rrenumd/lexer.l +++ b/usr.sbin/rrenumd/lexer.l @@ -1,3 +1,5 @@ +/* $KAME$ */ + /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. @@ -37,16 +39,21 @@ #include <string.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 <netinet/icmp6.h> + +#include <arpa/inet.h> + #include "y.tab.h" int lineno = 1; -#define LINEBUF_SIZE 1000 +#define LINEBUF_SIZE 1000 char linebuf[LINEBUF_SIZE]; %} @@ -209,6 +216,15 @@ off { yylval.cs.len = yyleng; return NAME; } +{ipv4addr} { + memset(&yylval.addr4, 0, sizeof(struct in_addr)); + if (inet_pton(AF_INET, yytext, + &yylval.addr4) == 1) { + return IPV4ADDR; + } else { + return ERROR; + } + } {ipv6addr} { memset(&yylval.addr6, 0, sizeof(struct in6_addr)); if (inet_pton(AF_INET6, yytext, diff --git a/usr.sbin/rrenumd/parser.y b/usr.sbin/rrenumd/parser.y index eecc7bb94a0a2..15ca06dd2f447 100644 --- a/usr.sbin/rrenumd/parser.y +++ b/usr.sbin/rrenumd/parser.y @@ -1,3 +1,5 @@ +/* $KAME$ */ + /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. @@ -36,7 +38,9 @@ #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 <netinet/in_var.h> @@ -48,40 +52,40 @@ #include "rrenumd.h" struct config_is_set { - u_short cis_dest : 1; + u_short cis_dest : 1; } cis; -struct dst_list *dl_head; -struct payload_list *pl_head, ple_cur; -u_int retry; -char errbuf[LINE_MAX]; +struct dst_list *dl_head; +struct payload_list *pl_head, ple_cur; +u_int retry; +char errbuf[LINE_MAX]; -extern int lineno; -extern void yyerror __P((const char *s)); -static struct payload_list * pllist_lookup __P((int seqnum)); -static void pllist_enqueue __P((struct payload_list *pl_entry)); +extern int lineno; +extern void yyerror __P((const char *s)); +static struct payload_list * pllist_lookup __P((int seqnum)); +static void pllist_enqueue __P((struct payload_list *pl_entry)); -#define MAX_RETRYNUM 10 /* upper limit of retry in this rrenumd program */ -#define MAX_SEQNUM 256 /* upper limit of seqnum in this rrenumd program */ -#define NOSPEC -1 +#define MAX_RETRYNUM 10 /* upper limit of retry in this rrenumd program */ +#define MAX_SEQNUM 256 /* upper limit of seqnum in this rrenumd program */ +#define NOSPEC -1 %} %union { - u_long num; + u_long num; struct { - char *cp; - int len; + char *cp; + int len; } cs; - struct in_addr addr4; - struct in6_addr addr6; + struct in_addr addr4; + struct in6_addr addr6; struct { - struct in6_addr addr; - u_char plen; + struct in6_addr addr; + u_char plen; } prefix; - struct dst_list *dl; - struct payload_list *pl; - struct sockaddr *sa; + struct dst_list *dl; + struct payload_list *pl; + struct sockaddr *sa; } %token <num> ADD CHANGE SETGLOBAL @@ -103,7 +107,7 @@ static void pllist_enqueue __P((struct payload_list *pl_entry)); %type <num> lifetime days hours minutes seconds %type <num> decstring %type <num> raf_onlink raf_auto raf_decrvalid raf_decrprefd flag -%type <dl> dest_addrs dest_addr sin6 +%type <dl> dest_addrs dest_addr sin sin6 %type <pl> rrenum_statement %type <cs> ifname %type <prefix> prefixval @@ -158,7 +162,11 @@ dest_addrs: ; dest_addr : - sin6 + sin + { + with_v4dest = 1; + } + | sin6 { with_v6dest = 1; } @@ -179,7 +187,7 @@ dest_addr : memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; - hints.ai_family = AF_INET6; + hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_RAW; hints.ai_protocol = 0; error = getaddrinfo($1.cp, 0, &hints, &res); @@ -200,6 +208,24 @@ dest_addr : } ; +sin: + IPV4ADDR + { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)malloc(sizeof(*sin)); + memset(sin, 0, sizeof(*sin)); + sin->sin_len = sizeof(*sin); + sin->sin_family = AF_INET; + sin->sin_addr = $1; + + $$ = (struct dst_list *) + malloc(sizeof(struct dst_list)); + memset($$, 0, sizeof(struct dst_list)); + $$->dl_dst = (struct sockaddr *)sin; + } + ; + sin6: IPV6ADDR { @@ -427,39 +453,43 @@ use_prefix_values: rpu->rpu_vltime = $2; rpu->rpu_pltime = $3; - if ($4 == NOSPEC) + if ($4 == NOSPEC) { rpu->rpu_ramask &= - ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; - else { + ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; + } else { rpu->rpu_ramask |= - ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; - if ($4 == ON) + ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; + if ($4 == ON) { rpu->rpu_raflags |= - ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; - else + ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; + } else { rpu->rpu_raflags &= - ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; + ~ICMP6_RR_PCOUSE_RAFLAGS_ONLINK; + } } - if ($5 == NOSPEC) + if ($5 == NOSPEC) { rpu->rpu_ramask &= - ICMP6_RR_PCOUSE_RAFLAGS_AUTO; - else { + ICMP6_RR_PCOUSE_RAFLAGS_AUTO; + } else { rpu->rpu_ramask |= - ICMP6_RR_PCOUSE_RAFLAGS_AUTO; - if ($5 == ON) + ICMP6_RR_PCOUSE_RAFLAGS_AUTO; + if ($5 == ON) { rpu->rpu_raflags |= - ICMP6_RR_PCOUSE_RAFLAGS_AUTO; - else + ICMP6_RR_PCOUSE_RAFLAGS_AUTO; + } else { rpu->rpu_raflags &= - ~ICMP6_RR_PCOUSE_RAFLAGS_AUTO; + ~ICMP6_RR_PCOUSE_RAFLAGS_AUTO; + } } rpu->rpu_flags = 0; - if ($6 == ON) + if ($6 == ON) { rpu->rpu_flags |= - ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME; - if ($7 == ON) + ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME; + } + if ($7 == ON) { rpu->rpu_flags |= - ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME; + ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME; + } } ; diff --git a/usr.sbin/rrenumd/rrenumd.8 b/usr.sbin/rrenumd/rrenumd.8 index d86633d01a0e9..6268bdc5af5a1 100644 --- a/usr.sbin/rrenumd/rrenumd.8 +++ b/usr.sbin/rrenumd/rrenumd.8 @@ -1,3 +1,5 @@ +.\" $KAME$ +.\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. .\" @@ -25,12 +27,11 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: rrenumd.8,v 1.1.1.1 1999/08/08 23:31:38 itojun Exp $ .\" $FreeBSD$ .\" .Dd Sep 7, 1998 .Dt RRENUMD 8 -.Os KAME +.Os .Sh NAME .Nm rrenumd .Nd router renumbering daemon @@ -39,7 +40,6 @@ .Oo .Fl c Ar conf_file | Fl s .Oc -.Op Fl P Ar policy .Op Fl df .Sh DESCRIPTION .Nm Rrenumd @@ -72,13 +72,6 @@ Do not become daemon. .It Fl s Script mode. Configuration information is obtained from standard input. -.It Fl P Ar policy -.Ar policy -specifies IPsec policy for the rrenumd session. -For details please refer to -.Xr ipsec 4 -and -.Xr ipsec_set_policy 3 . .It Fl c Ar conf_file Specify a configuration file where configuration information is kept. .Sh RETURN VALUES diff --git a/usr.sbin/rrenumd/rrenumd.c b/usr.sbin/rrenumd/rrenumd.c index ced5afc0a924a..9d150ac6f81e5 100644 --- a/usr.sbin/rrenumd/rrenumd.c +++ b/usr.sbin/rrenumd/rrenumd.c @@ -1,3 +1,5 @@ +/* $KAME$ */ + /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. @@ -44,11 +46,14 @@ #include <netinet/ip6.h> #include <netinet/icmp6.h> +#include <arpa/inet.h> + #ifdef IPSEC #include <netinet6/ipsec.h> #endif #include <stdio.h> +#include <err.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> @@ -56,36 +61,39 @@ #include "rrenumd.h" -#define LL_ALLROUTERS "ff02::2" -#define SL_ALLROUTERS "ff05::2" +#define LL_ALLROUTERS "ff02::2" +#define SL_ALLROUTERS "ff05::2" #ifndef IN6_IS_SCOPE_LINKLOCAL -#define IN6_IS_SCOPE_LINKLOCAL(a) \ +#define IN6_IS_SCOPE_LINKLOCAL(a) \ ((IN6_IS_ADDR_LINKLOCAL(a)) || \ (IN6_IS_ADDR_MC_LINKLOCAL(a))) #endif /* IN6_IS_SCOPE_LINKLOCAL */ struct flags { - u_long debug : 1; - u_long fg : 1; + u_long debug : 1; + u_long fg : 1; #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC - u_long policy : 1; + u_long policy : 1; +#else /* IPSEC_POLICY_IPSEC */ + u_long auth : 1; + u_long encrypt : 1; #endif /* IPSEC_POLICY_IPSEC */ #endif /*IPSEC*/ }; -struct msghdr sndmhdr; -struct msghdr rcvmhdr; -struct sockaddr_in6 from; -struct sockaddr_in6 sin6_ll_allrouters; +struct msghdr sndmhdr; +struct msghdr rcvmhdr; +struct sockaddr_in6 from; +struct sockaddr_in6 sin6_ll_allrouters; -int s6; -int with_v6dest; -struct in6_addr prefix; /* ADHOC */ -int prefixlen = 64; /* ADHOC */ +int s4, s6; +int with_v4dest, with_v6dest; +struct in6_addr prefix; /* ADHOC */ +int prefixlen = 64; /* ADHOC */ -extern int parse(FILE **fp); +extern int parse(FILE **fp); /* Print usage. Don't call this after daemonized. */ static void @@ -95,6 +103,8 @@ show_usage() #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC "] [-P policy" +#else /* IPSEC_POLICY_IPSEC */ + "AE" #endif /* IPSEC_POLICY_IPSEC */ #endif /* IPSEC */ "]\n"); @@ -111,15 +121,44 @@ init_sin6(struct sockaddr_in6 *sin6, const char *addr_ascii) ; /* XXX do something */ } +#if 0 /* XXX: not necessary ?? */ +void +join_multi(const char *addrname) +{ + struct ipv6_mreq mreq; + + if (inet_pton(AF_INET6, addrname, &mreq.ipv6mr_multiaddr.s6_addr) + != 1) { + syslog(LOG_ERR, "<%s> inet_pton failed(library bug?)", + __FUNCTION__); + exit(1); + } + /* ADHOC: currently join only one */ + { + if ((mreq.ipv6mr_interface = if_nametoindex(ifname)) == 0) { + syslog(LOG_ERR, "<%s> ifname %s should be invalid: %s", + __FUNCTION__, ifname, strerror(errno)); + exit(1); + } + if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, + &mreq, + sizeof(mreq)) < 0) { + syslog(LOG_ERR, "<%s> IPV6_JOIN_GROUP on %s: %s", + __FUNCTION__, ifname, strerror(errno)); + exit(1); + } + } +} +#endif + void init_globals() { static struct iovec rcviov; static u_char rprdata[4500]; /* maximal MTU of connected links */ - 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))]; + static u_char *rcvcmsgbuf = NULL; + static u_char *sndcmsgbuf = NULL; + int sndcmsglen, rcvcmsglen; /* init ll_allrouters */ init_sin6(&sin6_ll_allrouters, LL_ALLROUTERS); @@ -130,14 +169,28 @@ init_globals() rcvmhdr.msg_namelen = sizeof(struct sockaddr_in6); rcvmhdr.msg_iov = &rcviov; rcvmhdr.msg_iovlen = 1; + rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + if (rcvcmsgbuf == NULL && + (rcvcmsgbuf = (u_char *)malloc(rcvcmsglen)) == NULL) { + syslog(LOG_ERR, "<%s>: malloc failed", __FUNCTION__); + exit(1); + } rcvmhdr.msg_control = (caddr_t)rcvcmsgbuf; - rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf); + rcvmhdr.msg_controllen = rcvcmsglen; /* initialize msghdr for sending packets */ sndmhdr.msg_namelen = sizeof(struct sockaddr_in6); sndmhdr.msg_iovlen = 1; + sndcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + if (sndcmsgbuf == NULL && + (sndcmsgbuf = (u_char *)malloc(sndcmsglen)) == NULL) { + syslog(LOG_ERR, "<%s>: malloc failed", __FUNCTION__); + exit(1); + } sndmhdr.msg_control = (caddr_t)sndcmsgbuf; - sndmhdr.msg_controllen = sizeof(sndcmsgbuf); + sndmhdr.msg_controllen = sndcmsglen; } void @@ -191,7 +244,12 @@ sock6_open(struct flags *flags ) { struct icmp6_filter filt; - int on, optval; + int on; +#ifdef IPSEC +#ifndef IPSEC_POLICY_IPSEC + int optval; +#endif +#endif if (with_v6dest == 0) return; @@ -202,7 +260,13 @@ sock6_open(struct flags *flags exit(1); } - /* join all routers multicast addresses, not necessary? */ + /* + * join all routers multicast addresses. + */ +#if 0 /* XXX: not necessary ?? */ + join_multi(LL_ALLROUTERS); + join_multi(SL_ALLROUTERS); +#endif /* set icmpv6 filter */ ICMP6_FILTER_SETBLOCKALL(&filt); @@ -236,6 +300,91 @@ sock6_open(struct flags *flags err(1, NULL); free(buf); } +#else /* IPSEC_POLICY_IPSEC */ + if (flags->auth) { + optval = IPSEC_LEVEL_REQUIRE; + if (setsockopt(s6, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, + &optval, sizeof(optval)) == -1) { + syslog(LOG_ERR, "<%s> IPV6_AUTH_TRANS_LEVEL: %s", + __FUNCTION__, strerror(errno)); + exit(1); + } + } + if (flags->encrypt) { + optval = IPSEC_LEVEL_REQUIRE; + if (setsockopt(s6, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, + &optval, sizeof(optval)) == -1) { + syslog(LOG_ERR, "<%s> IPV6_ESP_TRANS_LEVEL: %s", + __FUNCTION__, strerror(errno)); + exit(1); + } + } +#endif /* IPSEC_POLICY_IPSEC */ +#endif /* IPSEC */ + + return; +} + +void +sock4_open(struct flags *flags +#ifdef IPSEC_POLICY_IPSEC + , char *policy +#endif /* IPSEC_POLICY_IPSEC */ + ) +{ +#ifdef IPSEC +#ifndef IPSEC_POLICY_IPSEC + int optval; +#endif +#endif + + if (with_v4dest == 0) + return; + if ((s4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { + syslog(LOG_ERR, "<%s> socket(v4): %s", __FUNCTION__, + strerror(errno)); + exit(1); + } + +#if 0 /* XXX: not necessary ?? */ + /* + * join all routers multicast addresses. + */ + some_join_function(); +#endif + +#ifdef IPSEC +#ifdef IPSEC_POLICY_IPSEC + if (flags->policy) { + char *buf; + buf = ipsec_set_policy(policy, strlen(policy)); + if (buf == NULL) + errx(1, ipsec_strerror()); + /* XXX should handle in/out bound policy. */ + if (setsockopt(s4, IPPROTO_IP, IP_IPSEC_POLICY, + buf, ipsec_get_policylen(buf)) < 0) + err(1, NULL); + free(buf); + } +#else /* IPSEC_POLICY_IPSEC */ + if (flags->auth) { + optval = IPSEC_LEVEL_REQUIRE; + if (setsockopt(s4, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, + &optval, sizeof(optval)) == -1) { + syslog(LOG_ERR, "<%s> IP_AUTH_TRANS_LEVEL: %s", + __FUNCTION__, strerror(errno)); + exit(1); + } + } + if (flags->encrypt) { + optval = IPSEC_LEVEL_REQUIRE; + if (setsockopt(s4, IPPROTO_IP, IP_ESP_TRANS_LEVEL, + &optval, sizeof(optval)) == -1) { + syslog(LOG_ERR, "<%s> IP_ESP_TRANS_LEVEL: %s", + __FUNCTION__, strerror(errno)); + exit(1); + } + } #endif /* IPSEC_POLICY_IPSEC */ #endif /* IPSEC */ @@ -248,7 +397,6 @@ rrenum_output(struct payload_list *pl, struct dst_list *dl) int i, msglen = 0; struct cmsghdr *cm; struct in6_pktinfo *pi; - struct icmp6_router_renum *rr; struct sockaddr_in6 *sin6 = NULL; sndmhdr.msg_name = (caddr_t)dl->dl_dst; @@ -267,7 +415,7 @@ rrenum_output(struct payload_list *pl, struct dst_list *dl) pi = (struct in6_pktinfo *)CMSG_DATA(cm); memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*XXX*/ pi->ipi6_ifindex = sin6->sin6_scope_id; - msglen += CMSG_SPACE(sizeof(struct in6_pktinfo)); + msglen += CMSG_LEN(sizeof(struct in6_pktinfo)); /* specify the hop limit of the packet if dest is link local */ /* not defined by router-renum-05.txt, but maybe its OK */ @@ -276,14 +424,14 @@ rrenum_output(struct payload_list *pl, struct dst_list *dl) cm->cmsg_type = IPV6_HOPLIMIT; cm->cmsg_len = CMSG_LEN(sizeof(int)); memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int)); - msglen += CMSG_SPACE(sizeof(int)); + msglen += CMSG_LEN(sizeof(int)); } sndmhdr.msg_controllen = msglen; if (sndmhdr.msg_controllen == 0) sndmhdr.msg_control = 0; sndmhdr.msg_iov = &pl->pl_sndiov; - i = sendmsg(s6, &sndmhdr, 0); + i = sendmsg(dl->dl_dst->sa_family == AF_INET ? s4 : s6, &sndmhdr, 0); if (i < 0 || i != sndmhdr.msg_iov->iov_len) syslog(LOG_ERR, "<%s> sendmsg: %s", __FUNCTION__, @@ -322,12 +470,19 @@ rrenum_input(int s) strerror(errno)); return; } + if (s == s4) + i -= sizeof(struct ip); if (i < sizeof(struct icmp6_router_renum)) { syslog(LOG_ERR, "<%s> packet size(%d) is too short", __FUNCTION__, i); return; } - rr = (struct icmp6_router_renum *)rcvmhdr.msg_iov->iov_base; + if (s == s4) { + struct ip *ip = (struct ip *)rcvmhdr.msg_iov->iov_base; + + rr = (struct icmp6_router_renum *)(ip + 1); + } else /* s == s6 */ + rr = (struct icmp6_router_renum *)rcvmhdr.msg_iov->iov_base; switch(rr->rr_code) { case ICMP6_ROUTER_RENUMBERING_COMMAND: @@ -337,7 +492,7 @@ rrenum_input(int s) /* TODO: receiving result message */ break; default: - syslog(LOG_ERR, "<%s> received unknown code %d" + syslog(LOG_ERR, "<%s> received unknown code %d", __FUNCTION__, rr->rr_code); break; } @@ -346,7 +501,6 @@ rrenum_input(int s) int main(int argc, char *argv[]) { - char *cfile = NULL; FILE *fp = stdin; fd_set fdset; struct timeval timeout; @@ -358,13 +512,15 @@ main(int argc, char *argv[]) #endif memset(&flags, 0, sizeof(flags)); - openlog(*argv, LOG_PID, LOG_DAEMON); + openlog("rrenumd", LOG_PID, LOG_DAEMON); /* get options */ while ((ch = getopt(argc, argv, "c:sdf" #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC - "P:" + "P" +#else /* IPSEC_POLICY_IPSEC */ + "AE" #endif /* IPSEC_POLICY_IPSEC */ #endif /* IPSEC */ )) != -1){ @@ -392,6 +548,13 @@ main(int argc, char *argv[]) flags.policy = 1; policy = strdup(optarg); break; +#else /* IPSEC_POLICY_IPSEC */ + case 'A': + flags.auth = 1; + break; + case 'E': + flags.encrypt = 1; + break; #endif /* IPSEC_POLICY_IPSEC */ #endif /*IPSEC*/ default: @@ -417,6 +580,11 @@ main(int argc, char *argv[]) , policy #endif /* IPSEC_POLICY_IPSEC */ ); + sock4_open(&flags +#ifdef IPSEC_POLICY_IPSEC + , policy +#endif /* IPSEC_POLICY_IPSEC */ + ); if (!flags.fg) daemon(0, 0); @@ -427,6 +595,11 @@ main(int argc, char *argv[]) if (s6 > maxfd) maxfd = s6; } + if (with_v4dest) { + FD_SET(s4, &fdset); + if (s4 > maxfd) + maxfd = s4; + } /* ADHOC: timeout each 30seconds */ memset(&timeout, 0, sizeof(timeout)); @@ -454,6 +627,8 @@ main(int argc, char *argv[]) send_counter = retry + 1; } } + if (FD_ISSET(s4, &select_fd)) + rrenum_input(s4); if (FD_ISSET(s6, &select_fd)) rrenum_input(s6); } diff --git a/usr.sbin/rrenumd/rrenumd.conf.5 b/usr.sbin/rrenumd/rrenumd.conf.5 index 06bccbf4979f2..c5aec2f1401ae 100644 --- a/usr.sbin/rrenumd/rrenumd.conf.5 +++ b/usr.sbin/rrenumd/rrenumd.conf.5 @@ -1,3 +1,5 @@ +.\" $KAME$ +.\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. .\" @@ -25,7 +27,6 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: rrenumd.conf.5,v 1.1.1.1 1999/08/08 23:31:39 itojun Exp $ .\" $FreeBSD$ .\" .Dd Nov 5, 1998 @@ -61,15 +62,15 @@ square brackets (`[' and `]') are used to show optional keywords and parameters. The vertical bar (`|') is used to indicate between a choice of optional parameters. -Curly braces (`{' and -`}') are used to group keywords and parameters when necessary. +Parentheses (`(' and +`)') are used to group keywords and parameters when necessary. .\" .Sh Interface specification There are some statements that may or have to specify interface. Interfaces are specified in the form of "name unit", such as .Ar lo0 and -.Ar ep1 . +.Ar ep1. .\" .Sh Configuration Statements .Bl -tag -width Ds @@ -83,8 +84,7 @@ then debugging is enabled, If .Ic off is specified, -then debugging is disabled. -It is disabled by default. +then debugging is disabled. It is disabled by default. .\" .It Ic dest Ar dest-list Op Ar retrycmd ; Specifies destinations to which router renumbering messages should be @@ -164,7 +164,7 @@ copied to the starting part of prefixes to be added on .Cm add|change|setglobal command, as decimal bit number. .It Cm keeplen Ar keeplen-val -Specify the medium part of +Specify the midium part of .Ar use-prefix-val just next to the starting part specified by .Ar use-prefix-len @@ -181,8 +181,7 @@ 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 +"m" means minutes, "s" means seconds. And alternatively, special keyword "infinity" can be also be specified. .It Cm pltime Ar pltime-val Assign an @@ -194,48 +193,38 @@ is same as for .Ar vltime-val . .It Cm raf_onlink Cm on|off Let the prefix to be added to have on-link or off-link nature -for the assigned interface. -If +for the assigned interface. If .Cm on -is specified, the prefix have on-link nature. -(e.g. the prefix +is specified, the prefix have on-link nature. (e.g. the prefix belong to the link) If .Cm off -is specified, the prefix have off-link nature. -(e.g. the +is specified, the prefix have off-link nature. (e.g. the prefix does not belong to the link) .It Cm raf_auto Cm on|off Enable or disable the autonomous address auto configuration -for the prefix to be added. -If +for the prefix to be added. If .Cm on is specified, autonomous address auto configuration is -enabled. -If +enabled. If .Cm off is specified, it is disabled. .It Cm rrf_decrprefd Cm on|off -Enable or disable the decrementation of the pltime. -If +Enable or disable the decrementation of the pltime. If .Cm on -is specified, decrementation of the pltime is enabled. -If +is specified, decrementation of the pltime is enabled. If .Cm off is specified, decrementation of the pltime is disabled. .It Cm rrf_decrvalid Cm on|off -Enable or disable the decrementation of the vltime. -If +Enable or disable the decrementation of the vltime. If .Cm on -is specified, decrementation of the vltime is enabled. -If +is specified, decrementation of the vltime is enabled. If .Cm off is specified, decrementation of the vltime is disabled. .El .\" .It seqnum Ar seqnum-val { Ar rrenum-cmd } ; Specifies contents of sending router renumbering message with some -specific seqnum. -Multiple of this statement can be specified if they +specific seqnum. Multiple of this statement can be specified if they have different .Ar seqnum-val each other. @@ -246,11 +235,10 @@ has just same syntax with above add|change|setglobal statement. .Sh EXAMPLE For each configuration file example shown below, we suppose every IPv6 subnet has its own prefix beginning with -fec0:0:0::/48 and with its own subnet number. -(in this case, +fec0:0:0::/48 and with its own subnet number. (in this case, subnet number is 7th and 8th octet value of the prefix) .Pp -If you want to assign prefixes beginning with fec0:1:1::/48 +If you want to assigne prefixes beginning with fec0:1:1::/48 to each subnet, then following configuration will be enough, if each of your routers supports IPv6 multicast forwarding. The subnet number of the existing fec0:0:0::/48 prefix and the @@ -278,11 +266,10 @@ add match-prefix fec0:0:0:: /48 use-prefix fec0:1:1:: /48 keeplen 16; If you are going to do renumbering, then following procedure will be natural. .Bl -enum -offset indent .It -Assign new prefix. +Assigne new prefix. .It Set old prefix lifetimes to some appropriate transition -period. -In the followng example we use 1 week for valid +period. In the followng example we use 1 week for valid lifetime, and 0 for preferred lifetime. Also, enable old prefix lifetime expiration. (By default, it is static and does not expire) @@ -334,7 +321,7 @@ command is almost same with command except that it deletes all pre-defined IPv6 global address. .Sh SEE ALSO -.Xr rrenumd 8 , +.Xr rrenumd 8 .Xr prefix 8 .Sh HISTORY The diff --git a/usr.sbin/rrenumd/rrenumd.h b/usr.sbin/rrenumd/rrenumd.h index dae2cd0c9e42b..4854cb48b1e71 100644 --- a/usr.sbin/rrenumd/rrenumd.h +++ b/usr.sbin/rrenumd/rrenumd.h @@ -1,3 +1,5 @@ +/* $KAME$ */ + /* * Copyright (C) 1998 WIDE Project. * All rights reserved. @@ -34,24 +36,25 @@ */ struct dst_list { - struct dst_list *dl_next; - struct sockaddr *dl_dst; + struct dst_list * dl_next; + struct sockaddr * dl_dst; }; -extern struct dst_list *dl_head; +extern struct dst_list *dl_head; struct payload_list { - struct payload_list *pl_next; - struct iovec pl_sndiov; - struct icmp6_router_renum pl_irr; - struct rr_pco_match pl_rpm; + struct payload_list * pl_next; + struct iovec pl_sndiov; + struct icmp6_router_renum + pl_irr; + struct rr_pco_match pl_rpm; /* currently, support only 1 rr_pco_use field per packet */ - struct rr_pco_use pl_rpu; + struct rr_pco_use pl_rpu; }; -extern struct payload_list *pl_head; -extern u_int retry; -extern int with_v4dest, with_v6dest; +extern struct payload_list *pl_head; +extern u_int retry; +extern int with_v4dest, with_v6dest; -#define DEF_VLTIME 2592000 -#define DEF_PLTIME 604800 +#define DEF_VLTIME 2592000 +#define DEF_PLTIME 604800 diff --git a/usr.sbin/rtadvd/Makefile b/usr.sbin/rtadvd/Makefile index 7b5d2a8d2380b..32e64252308fb 100644 --- a/usr.sbin/rtadvd/Makefile +++ b/usr.sbin/rtadvd/Makefile @@ -14,11 +14,11 @@ # $FreeBSD$ PROG= rtadvd -SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c +SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c -CFLAGS+=-DINET6 -DIPSEC -LDADD+= -lcompat -lipsec -DPADD+= ${LIBCOMPAT} ${LIBIPSEC} +CFLAGS+=-DINET6 +LDADD+= -lcompat +DPADD+= ${LIBCOMPAT} MAN5= rtadvd.conf.5 MAN8= rtadvd.8 diff --git a/usr.sbin/rtadvd/advcap.c b/usr.sbin/rtadvd/advcap.c index f0825b543a917..868066df957ca 100644 --- a/usr.sbin/rtadvd/advcap.c +++ b/usr.sbin/rtadvd/advcap.c @@ -1,3 +1,5 @@ +/* $KAME: advcap.c,v 1.3 2000/05/16 13:34:13 itojun Exp $ */ + /* * Copyright (c) 1983 The Regents of the University of California. * All rights reserved. @@ -33,10 +35,6 @@ * $FreeBSD$ */ -#ifndef lint -static char sccsid[] = "@(#)remcap.c 5.5 (Berkeley) 2/2/91"; -#endif /* not lint */ - /* * remcap - routines for dealing with the remote host data base * @@ -66,6 +64,11 @@ static char sccsid[] = "@(#)remcap.c 5.5 (Berkeley) 2/2/91"; #define tgetflag agetflag #define tgetstr agetstr +#if 0 +#define V_TERMCAP "REMOTE" +#define V_TERM "HOST" +#endif + char *RM; /* @@ -82,22 +85,22 @@ char *RM; * doesn't, and because living w/o it is not hard. */ -static char *tbuf; -static int hopcount; /* detect infinite loops in termcap, init 0 */ +static char *tbuf; +static int hopcount; /* detect infinite loops in termcap, init 0 */ -static char *remotefile; +static char *remotefile; -extern char *conffile; +extern char *conffile; -int tgetent __P((char *, char *)); -int getent __P((char *, char *, char *)); -int tnchktc __P((void)); -int tnamatch __P((char *)); -static char *tskip __P((char *)); -int tgetnum __P((char *)); -int tgetflag __P((char *)); -char *tgetstr __P((char *, char **)); -static char *tdecode __P((char *, char **)); +int tgetent __P((char *, char *)); +int getent __P((char *, char *, char *)); +int tnchktc __P((void)); +int tnamatch __P((char *)); +static char *tskip __P((char *)); +int tgetnum __P((char *)); +int tgetflag __P((char *)); +char *tgetstr __P((char *, char **)); +static char *tdecode __P((char *, char **)); /* * Get an entry for terminal name in buffer bp, @@ -136,7 +139,7 @@ getent(bp, name, cp) tf = open(RM = cp, O_RDONLY); } if (tf < 0) { - syslog(LOG_WARNING, + syslog(LOG_INFO, "<%s> open: %s", __FUNCTION__, strerror(errno)); return (-2); } diff --git a/usr.sbin/rtadvd/advcap.h b/usr.sbin/rtadvd/advcap.h index 9c4520b3a7f80..40ed46aae4fba 100644 --- a/usr.sbin/rtadvd/advcap.h +++ b/usr.sbin/rtadvd/advcap.h @@ -1,3 +1,5 @@ +/* $KAME$ */ + /* * Copyright (C) 1994,1995 by Andrey A. Chernov, Moscow, Russia. * All rights reserved. @@ -35,10 +37,10 @@ __BEGIN_DECLS -extern int agetent __P((char *, const char *)); -extern int agetflag __P((const char *)); -extern int agetnum __P((const char *)); -extern char *agetstr __P((const char *, char **)); +extern int agetent __P((char *, const char *)); +extern int agetflag __P((const char *)); +extern int agetnum __P((const char *)); +extern char *agetstr __P((const char *, char **)); __END_DECLS diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c index 964c79c144b50..422011246b9c7 100644 --- a/usr.sbin/rtadvd/config.c +++ b/usr.sbin/rtadvd/config.c @@ -1,7 +1,9 @@ +/* $KAME: config.c,v 1.11 2000/05/16 13:34:13 itojun Exp $ */ + /* * 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: @@ -13,7 +15,7 @@ * 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 @@ -35,7 +37,9 @@ #include <sys/time.h> #include <net/if.h> +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 #include <net/if_var.h> +#endif /* __FreeBSD__ >= 3 */ #include <net/route.h> #include <net/if_dl.h> @@ -44,6 +48,9 @@ #include <netinet/ip6.h> #include <netinet6/ip6_var.h> #include <netinet/icmp6.h> +#ifdef MIP6 +#include <netinet6/mip6.h> +#endif #include <arpa/inet.h> @@ -52,6 +59,9 @@ #include <errno.h> #include <string.h> #include <stdlib.h> +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include <search.h> +#endif #include <unistd.h> #include "rtadvd.h" @@ -60,11 +70,10 @@ #include "if.h" #include "config.h" -static void makeentry __P((char *, int, char *, int)); -static void make_packet __P((struct rainfo *)); -static void get_prefix __P((struct rainfo *)); +static void makeentry __P((char *, int, char *, int)); +static void get_prefix __P((struct rainfo *)); -extern struct rainfo *ralist; +extern struct rainfo *ralist; void getconfig(intface) @@ -78,8 +87,8 @@ getconfig(intface) char *bp = buf; char *addr; -#define MUSTHAVE(var, cap) \ - { \ +#define MUSTHAVE(var, cap) \ + do { \ int t; \ if ((t = agetnum(cap)) < 0) { \ fprintf(stderr, "rtadvd: need %s for interface %s\n", \ @@ -87,12 +96,12 @@ getconfig(intface) exit(1); \ } \ var = t; \ - } -#define MAYHAVE(var, cap, def) \ - { \ + } while (0) +#define MAYHAVE(var, cap, def) \ + do { \ if ((var = agetnum(cap)) < 0) \ var = def; \ - } + } while (0) if ((stat = agetent(tbuf, intface)) <= 0) { memset(tbuf, 0, sizeof(tbuf)); @@ -136,7 +145,7 @@ getconfig(intface) MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL); if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) { syslog(LOG_ERR, - "<%s> maxinterval must be between %d and %d", + "<%s> maxinterval must be between %e and %u", __FUNCTION__, MIN_MAXINTERVAL, MAX_MAXINTERVAL); exit(1); } @@ -144,7 +153,7 @@ getconfig(intface) MAYHAVE(val, "mininterval", tmp->maxinterval/3); if (val < MIN_MININTERVAL || val > (tmp->maxinterval * 3) / 4) { syslog(LOG_ERR, - "<%s> mininterval must be between %d and %d", + "<%s> mininterval must be between %e and %d", __FUNCTION__, MIN_MININTERVAL, (tmp->maxinterval * 3) / 4); @@ -158,6 +167,10 @@ getconfig(intface) MAYHAVE(val, "raflags", 0); tmp->managedflg= val & ND_RA_FLAG_MANAGED; tmp->otherflg = val & ND_RA_FLAG_OTHER; +#ifdef MIP6 + if (mobileip6) + tmp->haflg = val & ND_RA_FLAG_HA; +#endif MAYHAVE(val, "rltime", tmp->maxinterval * 3); if (val && (val < tmp->maxinterval || val > MAXROUTERLIFETIME)) { @@ -187,6 +200,39 @@ getconfig(intface) } tmp->retranstimer = (u_int32_t)val; +#ifdef MIP6 + if (!mobileip6) +#else + if (1) +#endif + { + if (agetstr("hapref", &bp) || agetstr("hatime", &bp)) { + syslog(LOG_ERR, + "<%s> mobile-ip6 configuration without " + "proper command line option", + __FUNCTION__); + exit(1); + } + } +#ifdef MIP6 + else { + tmp->hapref = 0; + if ((val = agetnum("hapref")) >= 0) + tmp->hapref = (int16_t)val; + if (tmp->hapref != 0) { + tmp->hatime = 0; + MUSTHAVE(val, "hatime"); + tmp->hatime = (u_int16_t)val; + if (tmp->hatime <= 0) { + syslog(LOG_ERR, + "<%s> home agent lifetime must be greater than 0", + __FUNCTION__); + exit(1); + } + } + } +#endif + /* prefix information */ if ((pfxs = agetnum("addrs")) < 0) { /* auto configure prefix information */ @@ -216,6 +262,8 @@ getconfig(intface) /* link into chain */ insque(pfx, &tmp->prefix); + pfx->origin = PREFIX_FROM_CONFIG; + makeentry(entbuf, i, "prefixlen", added); MAYHAVE(val, entbuf, 64); if (val < 0 || val > 128) { @@ -227,10 +275,24 @@ getconfig(intface) pfx->prefixlen = (int)val; makeentry(entbuf, i, "pinfoflags", added); - MAYHAVE(val, entbuf, - (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO)); +#ifdef MIP6 + if (mobileip6) + { + MAYHAVE(val, entbuf, + (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO| + ND_OPT_PI_FLAG_RTADDR)); + } else +#endif + { + MAYHAVE(val, entbuf, + (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO)); + } pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK; pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO; +#ifdef MIP6 + if (mobileip6) + pfx->routeraddr = val & ND_OPT_PI_FLAG_RTADDR; +#endif makeentry(entbuf, i, "vltime", added); MAYHAVE(val, entbuf, DEF_ADVVALIDLIFETIME); @@ -380,6 +442,7 @@ get_prefix(struct rainfo *rai) pp->preflifetime = DEF_ADVPREFERREDLIFETIME; pp->onlinkflg = 1; pp->autoconfflg = 1; + pp->origin = PREFIX_FROM_KERNEL; /* link into chain */ insque(pp, &rai->prefix); @@ -435,6 +498,7 @@ add_prefix(struct rainfo *rai, struct in6_prefixreq *ipr) prefix->preflifetime = ipr->ipr_pltime; prefix->onlinkflg = ipr->ipr_raf_onlink; prefix->autoconfflg = ipr->ipr_raf_auto; + prefix->origin = PREFIX_FROM_DYNAMIC; insque(prefix, &rai->prefix); @@ -462,7 +526,7 @@ add_prefix(struct rainfo *rai, struct in6_prefixreq *ipr) /* * Delete a prefix to the list of specified interface and reconstruct * the outgoing packet. - * The prefix must be in the list + * The prefix must be in the list. */ void delete_prefix(struct rainfo *rai, struct prefix *prefix) @@ -543,7 +607,7 @@ make_prefix(struct rainfo *rai, int ifindex, struct in6_addr *addr, int plen) add_prefix(rai, &ipr); } -static void +void make_packet(struct rainfo *rainfo) { size_t packlen, lladdroptlen = 0; @@ -551,6 +615,10 @@ make_packet(struct rainfo *rainfo) struct nd_router_advert *ra; struct nd_opt_prefix_info *ndopt_pi; struct nd_opt_mtu *ndopt_mtu; +#ifdef MIP6 + struct nd_opt_advint *ndopt_advint; + struct nd_opt_hai *ndopt_hai; +#endif struct prefix *pfx; /* calculate total length */ @@ -570,6 +638,12 @@ make_packet(struct rainfo *rainfo) packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs; if (rainfo->linkmtu) packlen += sizeof(struct nd_opt_mtu); +#ifdef MIP6 + if (mobileip6 && rainfo->maxinterval) + packlen += sizeof(struct nd_opt_advint); + if (mobileip6 && rainfo->hatime) + packlen += sizeof(struct nd_opt_hai); +#endif /* allocate memory for the packet */ if ((buf = malloc(packlen)) == NULL) { @@ -595,6 +669,10 @@ make_packet(struct rainfo *rainfo) rainfo->managedflg ? ND_RA_FLAG_MANAGED : 0; ra->nd_ra_flags_reserved |= rainfo->otherflg ? ND_RA_FLAG_OTHER : 0; +#ifdef MIP6 + ra->nd_ra_flags_reserved |= + rainfo->haflg ? ND_RA_FLAG_HA : 0; +#endif ra->nd_ra_router_lifetime = htons(rainfo->lifetime); ra->nd_ra_reachable = htonl(rainfo->reachabletime); ra->nd_ra_retransmit = htonl(rainfo->retranstimer); @@ -614,6 +692,30 @@ make_packet(struct rainfo *rainfo) buf += sizeof(struct nd_opt_mtu); } +#ifdef MIP6 + if (mobileip6 && rainfo->maxinterval) { + ndopt_advint = (struct nd_opt_advint *)buf; + ndopt_advint->nd_opt_int_type = ND_OPT_ADV_INTERVAL; + ndopt_advint->nd_opt_int_len = 1; + ndopt_advint->nd_opt_int_reserved = 0; + ndopt_advint->nd_opt_int_interval = ntohl(rainfo->maxinterval * + 1000); + buf += sizeof(struct nd_opt_advint); + } +#endif + +#ifdef MIP6 + if (rainfo->hatime) { + ndopt_hai = (struct nd_opt_hai *)buf; + ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION; + ndopt_hai->nd_opt_hai_len = 1; + ndopt_hai->nd_opt_hai_reserved = 0; + ndopt_hai->nd_opt_hai_pref = ntohs(rainfo->hapref); + ndopt_hai->nd_opt_hai_lifetime = ntohs(rainfo->hatime); + buf += sizeof(struct nd_opt_hai); + } +#endif + for (pfx = rainfo->prefix.next; pfx != &rainfo->prefix; pfx = pfx->next) { ndopt_pi = (struct nd_opt_prefix_info *)buf; @@ -627,6 +729,11 @@ make_packet(struct rainfo *rainfo) if (pfx->autoconfflg) ndopt_pi->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO; +#ifdef MIP6 + if (pfx->routeraddr) + ndopt_pi->nd_opt_pi_flags_reserved |= + ND_OPT_PI_FLAG_RTADDR; +#endif ndopt_pi->nd_opt_pi_valid_time = ntohl(pfx->validlifetime); ndopt_pi->nd_opt_pi_preferred_time = ntohl(pfx->preflifetime); diff --git a/usr.sbin/rtadvd/config.h b/usr.sbin/rtadvd/config.h index f8729d46a1d5b..76f42a0495ae2 100644 --- a/usr.sbin/rtadvd/config.h +++ b/usr.sbin/rtadvd/config.h @@ -1,7 +1,9 @@ +/* $KAME$ */ + /* * Copyright (C) 1995, 1996, 1997, 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: @@ -13,7 +15,7 @@ * 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 @@ -29,6 +31,7 @@ * $FreeBSD$ */ -extern void getconfig __P((char *)); -extern void delete_prefix __P((struct rainfo *, struct prefix *)); -extern void make_prefix __P((struct rainfo *, int, struct in6_addr *, int)); +extern void getconfig __P((char *)); +extern void delete_prefix __P((struct rainfo *, struct prefix *)); +extern void make_prefix __P((struct rainfo *, int, struct in6_addr *, int)); +extern void make_packet __P((struct rainfo *)); diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c index 81aa47d337618..99eec64b51e1b 100644 --- a/usr.sbin/rtadvd/if.c +++ b/usr.sbin/rtadvd/if.c @@ -1,7 +1,9 @@ +/* $KAME: if.c,v 1.9 2000/05/27 11:30:43 jinmei 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: @@ -13,7 +15,7 @@ * 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 @@ -35,11 +37,23 @@ #include <sys/ioctl.h> #include <net/if.h> #include <net/if_types.h> -#include <net/ethernet.h> +#ifdef __FreeBSD__ +# include <net/ethernet.h> +#endif +#include <ifaddrs.h> +#ifdef __NetBSD__ +#include <net/if_ether.h> +#endif #include <net/route.h> #include <net/if_dl.h> #include <netinet/in.h> #include <netinet/icmp6.h> +#ifdef __bsdi__ +# include <netinet/if_ether.h> +#endif +#ifdef __OpenBSD__ +#include <netinet/if_ether.h> +#endif #include <unistd.h> #include <errno.h> #include <stdlib.h> @@ -48,28 +62,28 @@ #include "rtadvd.h" #include "if.h" -#define ROUNDUP(a, size) \ +#define ROUNDUP(a, size) \ (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) -#define NEXT_SA(ap) (ap) = (struct sockaddr *) \ +#define NEXT_SA(ap) (ap) = (struct sockaddr *) \ ((caddr_t)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\ sizeof(u_long)) :\ sizeof(u_long))) -struct if_msghdr **iflist; -int iflist_init_ok; -size_t ifblock_size; -char *ifblock; +struct if_msghdr **iflist; +int iflist_init_ok; +size_t ifblock_size; +char *ifblock; -static void get_iflist __P((char **buf, size_t *size)); -static void parse_iflist __P((struct if_msghdr ***ifmlist_p, char *buf, +static void get_iflist __P((char **buf, size_t *size)); +static void parse_iflist __P((struct if_msghdr ***ifmlist_p, char *buf, size_t bufsize)); 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; @@ -108,6 +122,8 @@ if_nametosdl(char *name) if ((sa = rti_info[RTAX_IFP]) != NULL) { if (sa->sa_family == AF_LINK) { sdl = (struct sockaddr_dl *)sa; + if (strlen(name) != sdl->sdl_nlen) + continue; /* not same len */ if (strncmp(&sdl->sdl_data[0], name, sdl->sdl_nlen) == 0) { @@ -132,6 +148,7 @@ if_nametosdl(char *name) int if_getmtu(char *name) { +#if 0 struct ifreq ifr; int s; @@ -148,6 +165,25 @@ if_getmtu(char *name) close(s); return(ifr.ifr_mtu); +#else + struct ifaddrs *ifap, *ifa; + struct if_data *ifd; + + if (getifaddrs(&ifap) < 0) + return(0); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (strcmp(ifa->ifa_name, name) == 0) { + ifd = ifa->ifa_data; + freeifaddrs(ifap); + if (ifd) + return ifd->ifi_mtu; + else + return 0; + } + } + freeifaddrs(ifap); + return 0; +#endif } /* give interface index and its old flags, then new flags returned */ @@ -170,11 +206,10 @@ if_getflags(int ifindex, int oifflags) close(s); return (oifflags & ~IFF_UP); } - close(s); return (ifr.ifr_flags); } -#define ROUNDUP8(a) (1 + (((a) - 1) | 7)) +#define ROUNDUP8(a) (1 + (((a) - 1) | 7)) int lladdropt_length(struct sockaddr_dl *sdl) { @@ -233,9 +268,9 @@ get_rtinfo(char *buf, size_t *len) return(0); } -#define FILTER_MATCH(type, filter) ((0x1 << type) & filter) -#define SIN6(s) ((struct sockaddr_in6 *)(s)) -#define SDL(s) ((struct sockaddr_dl *)(s)) +#define FILTER_MATCH(type, filter) ((0x1 << type) & filter) +#define SIN6(s) ((struct sockaddr_in6 *)(s)) +#define SDL(s) ((struct sockaddr_dl *)(s)) char * get_next_msg(char *buf, char *lim, int ifindex, size_t *lenp, int filter) { @@ -377,7 +412,7 @@ get_prefixlen(char *buf) struct sockaddr *sa, *rti_info[RTAX_MAX]; int masklen; u_char *p, *lim; - + sa = (struct sockaddr *)(rtm + 1); get_rtaddrs(rtm->rtm_addrs, sa, rti_info); sa = rti_info[RTAX_NETMASK]; @@ -553,5 +588,4 @@ init_iflist() /* make list of pointers to each if_msghdr */ parse_iflist(&iflist, ifblock, ifblock_size); - } diff --git a/usr.sbin/rtadvd/if.h b/usr.sbin/rtadvd/if.h index e8e14d4203dd6..8d74557b4ba3c 100644 --- a/usr.sbin/rtadvd/if.h +++ b/usr.sbin/rtadvd/if.h @@ -1,7 +1,9 @@ +/* $KAME: if.h,v 1.2 2000/05/16 13:34:13 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 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: @@ -13,7 +15,7 @@ * 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 @@ -29,29 +31,30 @@ * $FreeBSD$ */ -#define RTADV_TYPE2BITMASK(type) (0x1 << type) +#define RTADV_TYPE2BITMASK(type) (0x1 << type) -extern struct if_msghdr **iflist; -extern size_t ifblock_size; -extern char *ifblock; +extern struct if_msghdr **iflist; +extern size_t ifblock_size; +extern char *ifblock; -struct sockaddr_dl *if_nametosdl __P((char *name)); -int if_getmtu __P((char *name)); -int if_getflags __P((int ifindex, int oifflags)); -int lladdropt_length __P((struct sockaddr_dl *sdl)); -void lladdropt_fill __P((struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt)); -int rtbuf_len __P((void)); -int get_rtinfo __P((char *buf, size_t *len)); -char *get_next_msg __P((char *buf, char *lim, int ifindex, size_t *lenp, +struct nd_opt_hdr; +struct sockaddr_dl *if_nametosdl __P((char *name)); +int if_getmtu __P((char *name)); +int if_getflags __P((int ifindex, int oifflags)); +int lladdropt_length __P((struct sockaddr_dl *sdl)); +void lladdropt_fill __P((struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt)); +int rtbuf_len __P((void)); +int get_rtinfo __P((char *buf, size_t *len)); +char *get_next_msg __P((char *buf, char *lim, int ifindex, size_t *lenp, int filter)); -struct in6_addr *get_addr __P((char *buf)); -int get_rtm_ifindex __P((char *buf)); -int get_ifm_ifindex __P((char *buf)); -int get_ifam_ifindex __P((char *buf)); -int get_ifm_flags __P((char *buf)); -int get_prefixlen __P((char *buf)); -int rtmsg_type __P((char *buf)); -int ifmsg_type __P((char *buf)); -int rtmsg_len __P((char *buf)); -int ifmsg_len __P((char *buf)); -void init_iflist __P((void)); +struct in6_addr *get_addr __P((char *buf)); +int get_rtm_ifindex __P((char *buf)); +int get_ifm_ifindex __P((char *buf)); +int get_ifam_ifindex __P((char *buf)); +int get_ifm_flags __P((char *buf)); +int get_prefixlen __P((char *buf)); +int rtmsg_type __P((char *buf)); +int ifmsg_type __P((char *buf)); +int rtmsg_len __P((char *buf)); +int ifmsg_len __P((char *buf)); +void init_iflist __P((void)); diff --git a/usr.sbin/rtadvd/pathnames.h b/usr.sbin/rtadvd/pathnames.h index cd8b0e0fdc4c3..85ca33c11da40 100644 --- a/usr.sbin/rtadvd/pathnames.h +++ b/usr.sbin/rtadvd/pathnames.h @@ -1,2 +1,4 @@ -/* $FreeBSD$ */ +/* $KAME$ */ +/* $FreeBSD$ */ + #define _PATH_RTADVDCONF "/etc/rtadvd.conf" diff --git a/usr.sbin/rtadvd/rrenum.c b/usr.sbin/rtadvd/rrenum.c index f4c71f1a5cd4a..f64ebc3c0546f 100644 --- a/usr.sbin/rtadvd/rrenum.c +++ b/usr.sbin/rtadvd/rrenum.c @@ -1,3 +1,5 @@ +/* $KAME: rrenum.c,v 1.3 2000/05/16 13:34:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. @@ -35,7 +37,9 @@ #include <sys/sysctl.h> #include <net/if.h> +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 #include <net/if_var.h> +#endif /* __FreeBSD__ >= 3 */ #include <net/route.h> #include <netinet/in.h> #include <netinet/in_var.h> @@ -60,14 +64,15 @@ struct rr_operation { u_long rro_segnum_bits[8]; }; -static struct rr_operation rro; -static int rr_rcvifindex; -static int rrcmd2pco[4] = {0, - SIOCAIFPREFIX_IN6, - SIOCCIFPREFIX_IN6, - SIOCSGIFPREFIX_IN6 +static struct rr_operation rro; +static int rr_rcvifindex; +static int rrcmd2pco[RPM_PCO_MAX] = { + 0, + SIOCAIFPREFIX_IN6, + SIOCCIFPREFIX_IN6, + SIOCSGIFPREFIX_IN6 }; -static int s; +static int s = -1; /* * Check validity of a Prefix Control Operation(PCO). @@ -206,6 +211,12 @@ do_pco(struct icmp6_router_renum *rr, int len, struct rr_pco_match *rpm) if ((rr_pco_check(len, rpm) != NULL)) return 1; + if (s == -1 && (s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__, + strerror(errno)); + exit(1); + } + memset(&irr, 0, sizeof(irr)); irr.irr_origin = PR_ORIG_RR; irr.irr_m_len = rpm->rpm_matchlen; @@ -254,12 +265,6 @@ do_rr(int len, struct icmp6_router_renum *rr) /* get iflist block from kernel again, to get up-to-date information */ init_iflist(); - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__, - strerror(errno)); - exit(1); - } - while (cp < lim) { int rpmlen; @@ -268,7 +273,6 @@ do_rr(int len, struct icmp6_router_renum *rr) tooshort: syslog(LOG_ERR, "<%s> pkt too short. left len = %d. " "gabage at end of pkt?", __FUNCTION__, len); - close(s); return 1; } rpmlen = rpm->rpm_len << 3; @@ -284,7 +288,7 @@ do_rr(int len, struct icmp6_router_renum *rr) cp += rpmlen; len -= rpmlen; } - close(s); + return 0; } diff --git a/usr.sbin/rtadvd/rrenum.h b/usr.sbin/rtadvd/rrenum.h index d3c73a7477f67..729b96fece3df 100644 --- a/usr.sbin/rtadvd/rrenum.h +++ b/usr.sbin/rtadvd/rrenum.h @@ -1,7 +1,9 @@ +/* $KAME$ */ + /* * 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: @@ -13,7 +15,7 @@ * 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 @@ -29,6 +31,6 @@ * $FreeBSD$ */ -void rr_input __P((int len, struct icmp6_router_renum *rr, +void rr_input __P((int len, struct icmp6_router_renum *rr, struct in6_pktinfo *pi, struct sockaddr_in6 *from, struct in6_addr *dst)); diff --git a/usr.sbin/rtadvd/rtadvd.8 b/usr.sbin/rtadvd/rtadvd.8 index 2c56bae092b2c..5f1f91b089160 100644 --- a/usr.sbin/rtadvd/rtadvd.8 +++ b/usr.sbin/rtadvd/rtadvd.8 @@ -1,3 +1,5 @@ +.\" $KAME: rtadvd.8,v 1.8 2000/05/22 22:12:11 itojun Exp $ +.\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. .\" @@ -25,59 +27,58 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: rtadvd.8,v 1.1.1.1 1999/08/08 23:31:42 itojun Exp $ -.\" $FreeBSD$ +.\" $FreeBSD$ .\" .Dd May 17, 1998 .Dt RTADVD 8 -.Os KAME +.Os .Sh NAME .Nm rtadvd .Nd router advertisement daemon .Sh SYNOPSIS .Nm .Op Fl c Ar configfile -.Op Fl P Ar policy -.Op Fl dDfs +.Op Fl dDfmRs .Ar interface ... .Sh DESCRIPTION -.Nm Rtadvd +.Nm advertises router advertisement packet to the specified .Ar interfaces . .Pp The program will daemonize itself on invocation. -Then, it will voluntarily send router advertisement packet periodically. -If a router solicitation packet from host has reached the program, -the program will respond by router advertisement packet. +It will then periodically send router advertisement packets, as well +as in response to router solicitation messages sent by end hosts. .Pp -For each interface, which is called advertising interface, -content of router advertisement can be described in +Router advertisements can be configured on a per-interface basis, as +described in .Xr rtadvd.conf 5 . .Pp -If there is no description for the interface in the configuration file -or if the configuration file does not exist, +In the event of no configuration file entry for an interface, +or if the configuration file does not exist altogether, .Nm sets all the parameters to their default values. In particular, .Nm -gets all the interface routes from the routing table and advertises +reads all the interface routes from the routing table and advertises them as on-link prefixes. .Pp -.Nm Rtadvd -watches the routing table. +.Nm +also watches the routing table. By default, if an interface direct route is -added/deleted on an advertising interface, +added/deleted on an advertising interface and no static prefixes are +specified by the configuration file, .Nm adds/deletes the corresponding prefix to/from its advertising list, respectively. -If you do not want to enable this feature, you should specify the +The .Ic Fl s -command line option when advocation. +may be used to disable this behavior. +Moreover, if the status of an advertising interface changes, +.Nm +will start or stop sending router advertisements according +to the latest status. .Pp -.Nm Rtadvd -can also receive router renumbering packets, and can do router -renumbering for the system it runs on, as the contents of those -packets. +The command line options are: .Bl -tag -width indent .\" .It Fl c @@ -87,37 +88,53 @@ for the configuration file. By default, .Pa /etc/rtadvd.conf is used. -.It Fl P -Specifies that -.Nm -receives router renumbering messages. -Also, specifies IPsec policy for -rrenumd sessions. -Because router renumbering can change the system's -IPv6 prefix, its messages must be protected by IPsec. -For details about -.Ar policy , -please refer to -.Xr ipsec 4 -and -.Xr ipsec_set_policy 3 . .It Fl d -Debug. +Print debugging information. .It Fl D -More debug. +Even more debugging information is printed. .It Fl f -Foreground mode. -Do not become daemon. +Foreground mode (useful when debugging). +.It Fl m +Enables mobile IPv6 support. +This changes the content of router advertisement option, as well as +permitted configuration directives. +.It Fl R +Accept router renumbering requests. +If you enable it, certain IPsec setup is suggested for security reasons. .It Fl s -Static prefix. -Do not watch the routing table. +Do not add or delete prefixes dynamically. +Only statically configured prefixes, if any, will be advertised. .El +.Pp +Upon receipt of signal +.Dv SIGUSR1 , +.Nm +will dump the current internal state into +.Pa /var/run/rtadvd.dump. +.Pp +Use +.Dv SIGTERM +to kill +.Nm +gracefully. +In this case, +.Nm +will transmit router advertisement with router lifetime 0 +to all the interfaces +.Pq according to RFC2461 6.2.5 . .Sh RETURN VALUES The program exits with 0 on success, and non-zero on failures. .Sh FILES .Bl -tag -width /etc/rtadvd.conf -compact .It Pa /etc/rtadvd.conf The default configuration file. +.It Pa /var/run/rtadvd.pid +contains pid of the currently running +.Nm rtadvd . +.It Pa /var/run/rtadvd.dump +on which +.Nm +dumps its internal state. .El .Sh SEE ALSO .Xr daemon 3 , @@ -128,10 +145,9 @@ The .Nm command first appeared in WIDE Hydrangea IPv6 protocol stack kit. .Sh CAVEAT -Do not perform router advertisement toward upstream direction, -you should only advertise to downstream direction. -If you advertise toward upstream by mistake, -you will see icmp6 redirect storm on that subnet. -This is because of the specification, -which says that advertising router is assumed to become -the default outgoing router for end hosts in the subnet. +Router advertisements should only be performed downstream. +Erroneous upstream advertisements will cause +.Xr icmp6 4 +redirect packet storms in the subnet, as (per the specification) the +advertising router is assumed to become the default router for +end hosts in the subnet. diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c index d5a58459e19f3..1cd602eb788c0 100644 --- a/usr.sbin/rtadvd/rtadvd.c +++ b/usr.sbin/rtadvd/rtadvd.c @@ -1,7 +1,9 @@ +/* $KAME: rtadvd.c,v 1.30 2000/06/22 20:16:12 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: @@ -13,7 +15,7 @@ * 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 @@ -44,17 +46,13 @@ #include <arpa/inet.h> -#ifdef IPSEC -#include <netinet6/ipsec.h> -#endif /*IPSEC*/ - #include <time.h> #include <unistd.h> #include <stdio.h> +#include <stdlib.h> #include <err.h> #include <errno.h> #include <string.h> -#include <sysexits.h> #include <stdlib.h> #include <syslog.h> #include "rtadvd.h" @@ -63,74 +61,85 @@ #include "timer.h" #include "if.h" #include "config.h" +#include "dump.h" -struct msghdr rcvmhdr; -static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int))]; -struct msghdr sndmhdr; -struct iovec rcviov[2]; -struct iovec sndiov[2]; -struct sockaddr_in6 from; -struct sockaddr_in6 sin6_allnodes = {sizeof(sin6_allnodes), AF_INET6}; -int sock, rrsock, rtsock; -int accept_rr = 0; -int dflag = 0, sflag = 0; +struct msghdr rcvmhdr; +static u_char *rcvcmsgbuf; +static size_t rcvcmsgbuflen; +static u_char *sndcmsgbuf = NULL; +static size_t sndcmsgbuflen; +static int do_dump; +struct msghdr sndmhdr; +struct iovec rcviov[2]; +struct iovec sndiov[2]; +struct sockaddr_in6 from; +struct sockaddr_in6 sin6_allnodes = {sizeof(sin6_allnodes), AF_INET6}; +static char *dumpfilename = "/var/run/rtadvd.dump"; /* XXX: should be configurable */ +static char *pidfilename = "/var/run/rtadvd.pid"; /* should be configurable */ +int sock, rtsock; +#ifdef MIP6 +int mobileip6 = 0; +#endif +int accept_rr = 0; +int dflag = 0, sflag = 0; -u_char *conffile = NULL; +u_char *conffile = NULL; -struct rainfo *ralist = NULL; -struct nd_optlist { - struct nd_optlist *next; - struct nd_opt_hdr *opt; +struct rainfo *ralist = NULL; +struct nd_optlist { + struct nd_optlist *next; + struct nd_opt_hdr *opt; }; union nd_opts { - struct nd_opt_hdr *nd_opt_array[7]; + struct nd_opt_hdr *nd_opt_array[7]; struct { - struct nd_opt_hdr *zero; - struct nd_opt_hdr *src_lladdr; - struct nd_opt_hdr *tgt_lladdr; - struct nd_opt_prefix_info *pi; - struct nd_opt_rd_hdr *rh; - struct nd_opt_mtu *mtu; - struct nd_optlist *list; + struct nd_opt_hdr *zero; + struct nd_opt_hdr *src_lladdr; + struct nd_opt_hdr *tgt_lladdr; + struct nd_opt_prefix_info *pi; + struct nd_opt_rd_hdr *rh; + struct nd_opt_mtu *mtu; + struct nd_optlist *list; } nd_opt_each; }; -#define nd_opts_src_lladdr nd_opt_each.src_lladdr -#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr -#define nd_opts_pi nd_opt_each.pi -#define nd_opts_rh nd_opt_each.rh -#define nd_opts_mtu nd_opt_each.mtu -#define nd_opts_list nd_opt_each.list +#define nd_opts_src_lladdr nd_opt_each.src_lladdr +#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr +#define nd_opts_pi nd_opt_each.pi +#define nd_opts_rh nd_opt_each.rh +#define nd_opts_mtu nd_opt_each.mtu +#define nd_opts_list nd_opt_each.list -#define NDOPT_FLAG_SRCLINKADDR 0x1 -#define NDOPT_FLAG_TGTLINKADDR 0x2 -#define NDOPT_FLAG_PREFIXINFO 0x4 -#define NDOPT_FLAG_RDHDR 0x8 -#define NDOPT_FLAG_MTU 0x10 +#define NDOPT_FLAG_SRCLINKADDR 0x1 +#define NDOPT_FLAG_TGTLINKADDR 0x2 +#define NDOPT_FLAG_PREFIXINFO 0x4 +#define NDOPT_FLAG_RDHDR 0x8 +#define NDOPT_FLAG_MTU 0x10 u_int32_t ndopt_flags[] = { 0, NDOPT_FLAG_SRCLINKADDR, NDOPT_FLAG_TGTLINKADDR, NDOPT_FLAG_PREFIXINFO, NDOPT_FLAG_RDHDR, NDOPT_FLAG_MTU }; -int main __P((int, char *[])); -static void sock_open __P((int *, int, char *)); -static void rtsock_open __P((void)); -static void rtadvd_input __P((int)); -static void rs_input __P((int, struct nd_router_solicit *, +int main __P((int, char *[])); +static void die __P((int)); +static void sock_open __P((void)); +static void rtsock_open __P((void)); +static void rtadvd_input __P((void)); +static void rs_input __P((int, struct nd_router_solicit *, struct in6_pktinfo *, struct sockaddr_in6 *)); -static void ra_input __P((int, struct nd_router_advert *, +static void ra_input __P((int, struct nd_router_advert *, struct in6_pktinfo *, struct sockaddr_in6 *)); -static void prefix_check __P((struct nd_opt_prefix_info *, struct rainfo *, - struct sockaddr_in6 *)); -static int nd6_options __P((struct nd_opt_hdr *, int, +static int prefix_check __P((struct nd_opt_prefix_info *, struct rainfo *, + struct sockaddr_in6 *)); +static int nd6_options __P((struct nd_opt_hdr *, int, union nd_opts *, u_int32_t)); -static void free_ndopts __P((union nd_opts *)); -static struct rainfo *if_indextorainfo __P((int)); -static void ra_output __P((struct rainfo *)); -static void rtmsg_input __P((void)); -struct prefix *find_prefix __P((struct rainfo *, struct in6_addr *, int)); +static void free_ndopts __P((union nd_opts *)); +static struct rainfo *if_indextorainfo __P((int)); +static void ra_output __P((struct rainfo *)); +static void rtmsg_input __P((void)); +static void rtadvd_set_dump_file __P((void)); +struct prefix *find_prefix __P((struct rainfo *, struct in6_addr *, int)); int main(argc, argv) @@ -142,21 +151,19 @@ main(argc, argv) struct timeval *timeout; int i, ch; int fflag = 0; -#ifdef IPSEC -#ifdef IPSEC_POLICY_IPSEC - char *policy = NULL; -#endif /*IPSEC_POLICY_IPSEC*/ -#endif /*IPSEC*/ + FILE *pidfp; + pid_t pid; - openlog(*argv, LOG_NDELAY|LOG_PID, LOG_DAEMON); + openlog("rtadvd", LOG_NDELAY|LOG_PID, LOG_DAEMON); /* get command line options and arguments */ -#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) - while ((ch = getopt(argc, argv, "c:dDfP:R:s")) != -1) +#ifdef MIP6 +#define OPTIONS "c:dDfmRs" #else - while ((ch = getopt(argc, argv, "c:dDfR:s")) != -1) +#define OPTIONS "c:dDfRs" #endif - { + while ((ch = getopt(argc, argv, OPTIONS)) != -1) { +#undef OPTIONS switch(ch) { case 'c': conffile = optarg; @@ -170,23 +177,28 @@ main(argc, argv) case 'f': fflag = 1; break; -#ifdef IPSEC -#ifdef IPSEC_POLICY_IPSEC - case 'P': - policy = strdup(optarg); +#ifdef MIP6 + case 'm': + mobileip6 = 1; + break; +#endif + case 'R': accept_rr = 1; break; -#endif /*IPSEC_POLICY_IPSEC*/ -#endif /*IPSEC*/ case 's': sflag = 1; + break; } } argc -= optind; argv += optind; if (argc == 0) { fprintf(stderr, - "usage: rtadvd [-c conffile] [-d|D] [-f] [-s]" +#ifdef MIP6 + "usage: rtadvd [-dDfmRs] [-c conffile] " +#else + "usage: rtadvd [-dDfRs] [-c conffile] " +#endif "interfaces...\n"); exit(1); } @@ -213,41 +225,63 @@ main(argc, argv) fprintf(stderr, "fatal: inet_pton failed\n"); exit(1); } - sock_open(&sock, 0, NULL); - if (accept_rr != 0) - sock_open(&rrsock, 1, policy); + sock_open(); if (!fflag) daemon(1, 0); + /* record the current PID */ + pid = getpid(); + if ((pidfp = fopen(pidfilename, "w")) == NULL) + syslog(LOG_ERR, + "<%s> failed to open a log file(%s), run anyway.", + __FUNCTION__, pidfilename); + else { + fprintf(pidfp, "%d\n", pid); + fclose(pidfp); + } + FD_ZERO(&fdset); FD_SET(sock, &fdset); - if (accept_rr) - FD_SET(rrsock, &fdset); - maxfd = sock > rrsock ? sock : rrsock; - if (sflag == 0) { - rtsock_open(); - FD_SET(rtsock, &fdset); - if (rtsock > maxfd) + maxfd = sock; + rtsock_open(); + FD_SET(rtsock, &fdset); + if (rtsock > sock) maxfd = rtsock; - } + + signal(SIGTERM, (void *)die); + signal(SIGUSR1, (void *)rtadvd_set_dump_file); while (1) { struct fd_set select_fd = fdset; /* reinitialize */ + if (do_dump) { /* SIGUSR1 */ + do_dump = 0; + rtadvd_dump_file(dumpfilename); + } + /* timer expiration check and reset the timer */ timeout = rtadvd_check_timer(); - syslog(LOG_DEBUG, - "<%s> set timer to %ld:%ld. waiting for inputs " - "or timeout", - __FUNCTION__, - timeout->tv_sec, timeout->tv_usec); + if (timeout != NULL) { + syslog(LOG_DEBUG, + "<%s> set timer to %ld:%ld. waiting for " + "inputs or timeout", + __FUNCTION__, + (long int)timeout->tv_sec, + (long int)timeout->tv_usec); + } else { + syslog(LOG_DEBUG, + "<%s> there's no timer. waiting for inputs", + __FUNCTION__); + } if ((i = select(maxfd + 1, &select_fd, - NULL, NULL, timeout)) < 0){ - syslog(LOG_ERR, "<%s> select: %s", - __FUNCTION__, strerror(errno)); + NULL, NULL, timeout)) < 0) { + /* EINTR would occur upon SIGUSR1 for status dump */ + if (errno != EINTR) + syslog(LOG_ERR, "<%s> select: %s", + __FUNCTION__, strerror(errno)); continue; } if (i == 0) /* timeout */ @@ -255,17 +289,47 @@ main(argc, argv) if (sflag == 0 && FD_ISSET(rtsock, &select_fd)) rtmsg_input(); if (FD_ISSET(sock, &select_fd)) - rtadvd_input(sock); - if (accept_rr && FD_ISSET(rrsock, &select_fd)) - rtadvd_input(rrsock); + rtadvd_input(); } exit(0); /* NOTREACHED */ } static void +rtadvd_set_dump_file() +{ + do_dump = 1; +} + +static void +die(sig) + int sig; +{ + struct rainfo *ra; + int i; + const int retrans = MAX_FINAL_RTR_ADVERTISEMENTS; + + if (dflag > 1) { + syslog(LOG_DEBUG, "<%s> cease to be an advertising router\n", + __FUNCTION__); + } + + for (ra = ralist; ra; ra = ra->next) { + ra->lifetime = 0; + make_packet(ra); + } + for (i = 0; i < retrans; i++) { + for (ra = ralist; ra; ra = ra->next) + ra_output(ra); + sleep(MIN_DELAY_BETWEEN_RAS); + } + exit(0); + /*NOTREACHED*/ +} + +static void rtmsg_input() { - int n, type, ifindex, plen; + int n, type, ifindex = 0, plen; size_t len; char msg[2048], *next, *lim; u_char ifname[16]; @@ -284,8 +348,8 @@ rtmsg_input() } if (n > rtmsg_len(msg)) { /* - * This usually won't happen for messages received on - * an routing socket. + * This usually won't happen for messages received on + * a routing socket. */ if (dflag > 1) syslog(LOG_DEBUG, @@ -293,10 +357,16 @@ rtmsg_input() "1st routing message len. multiple messages?" " read %d bytes, but 1st msg len = %d", __FUNCTION__, n, rtmsg_len(msg)); +#if 0 + /* adjust length */ + n = rtmsg_len(msg); +#endif } lim = msg + n; for (next = msg; next < lim; next += len) { + int oldifflags; + next = get_next_msg(next, lim, 0, &len, RTADV_TYPE2BITMASK(RTM_ADD) | RTADV_TYPE2BITMASK(RTM_DELETE) | @@ -326,7 +396,7 @@ rtmsg_input() __FUNCTION__, __LINE__, type, if_indextoname(ifindex, ifname)); } - return; + continue; } if ((rai = if_indextorainfo(ifindex)) == NULL) { @@ -337,16 +407,20 @@ rtmsg_input() __FUNCTION__, if_indextoname(ifindex, ifname)); } - return; + continue; } + oldifflags = iflist[ifindex]->ifm_flags; switch(type) { case RTM_ADD: - /* init iffalgs because it may have changed */ + /* init ifflags because it may have changed */ iflist[ifindex]->ifm_flags = if_getflags(ifindex, iflist[ifindex]->ifm_flags); + if (sflag) + break; /* we aren't interested in prefixes */ + addr = get_addr(msg); plen = get_prefixlen(msg); /* sanity check for plen */ @@ -355,7 +429,7 @@ rtmsg_input() syslog(LOG_INFO, "<%s> new interface route's" "plen %d is invalid for a prefix", __FUNCTION__, plen); - return; + break; } prefix = find_prefix(rai, addr, plen); if (prefix) { @@ -371,7 +445,7 @@ rtmsg_input() plen, rai->ifname); } - return; + break; } make_prefix(rai, ifindex, addr, plen); break; @@ -381,6 +455,9 @@ rtmsg_input() if_getflags(ifindex, iflist[ifindex]->ifm_flags); + if (sflag) + break; + addr = get_addr(msg); plen = get_prefixlen(msg); /* sanity check for plen */ @@ -390,7 +467,7 @@ rtmsg_input() "route's" "plen %d is invalid for a prefix", __FUNCTION__, plen); - return; + break; } prefix = find_prefix(rai, addr, plen); if (prefix == NULL) { @@ -406,7 +483,7 @@ rtmsg_input() plen, rai->ifname); } - return; + break; } delete_prefix(rai, prefix); break; @@ -430,16 +507,42 @@ rtmsg_input() } return; } + + /* check if an interface flag is changed */ + if ((oldifflags & IFF_UP) != 0 && /* UP to DOWN */ + (iflist[ifindex]->ifm_flags & IFF_UP) == 0) { + syslog(LOG_INFO, + "<%s> interface %s becomes down. stop timer.", + __FUNCTION__, rai->ifname); + rtadvd_remove_timer(&rai->timer); + } + else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */ + (iflist[ifindex]->ifm_flags & IFF_UP) != 0) { + syslog(LOG_INFO, + "<%s> interface %s becomes up. restart timer.", + __FUNCTION__, rai->ifname); + + rai->initcounter = 0; /* reset the counter */ + rai->waiting = 0; /* XXX */ + rai->timer = rtadvd_add_timer(ra_timeout, + ra_timer_update, + rai, rai); + ra_timer_update((void *)rai, &rai->timer->tm); + rtadvd_set_timer(&rai->timer->tm, rai->timer); + } } return; } void -rtadvd_input(skt) +rtadvd_input() { int i; int *hlimp = NULL; +#ifdef OLDRAWSOCKET + struct ip6_hdr *ip; +#endif struct icmp6_hdr *icp; int ifindex = 0; struct cmsghdr *cm; @@ -452,8 +555,8 @@ rtadvd_input(skt) * be modified if we had received a message before setting * receive options. */ - rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf); - if ((i = recvmsg(skt, &rcvmhdr, 0)) < 0) + rcvmhdr.msg_controllen = rcvcmsgbuflen; + if ((i = recvmsg(sock, &rcvmhdr, 0)) < 0) return; /* extract optional information via Advanced API */ @@ -485,6 +588,29 @@ rtadvd_input(skt) return; } + /* + * If we happen to receive data on an interface which is now down, + * just discard the data. + */ + if ((iflist[pi->ipi6_ifindex]->ifm_flags & IFF_UP) == 0) { + syslog(LOG_INFO, + "<%s> received data on a disabled interface (%s)", + __FUNCTION__, + if_indextoname(pi->ipi6_ifindex, ifnamebuf)); + return; + } + +#ifdef OLDRAWSOCKET + if (i < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr)) { + syslog(LOG_ERR, + "<%s> packet size(%d) is too short", + __FUNCTION__, i); + return; + } + + ip = (struct ip6_hdr *)rcvmhdr.msg_iov[0].iov_base; + icp = (struct icmp6_hdr *)(ip + 1); /* XXX: ext. hdr? */ +#else if (i < sizeof(struct icmp6_hdr)) { syslog(LOG_ERR, "<%s> packet size(%d) is too short", @@ -493,13 +619,18 @@ rtadvd_input(skt) } icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base; +#endif switch(icp->icmp6_type) { case ND_ROUTER_SOLICIT: - /* hop limit verification - RFC-2461 6.1.1 */ + /* + * Message verification - RFC-2461 6.1.1 + * XXX: these checks must be done in the kernel as well, + * but we can't completely rely on them. + */ if (*hlimp != 255) { syslog(LOG_NOTICE, - "<%s> invalid hop limit(%d) " + "<%s> RS with invalid hop limit(%d) " "received from %s on %s", __FUNCTION__, *hlimp, inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, @@ -507,13 +638,36 @@ rtadvd_input(skt) if_indextoname(pi->ipi6_ifindex, ifnamebuf)); return; } + if (icp->icmp6_code) { + syslog(LOG_NOTICE, + "<%s> RS with invalid ICMP6 code(%d) " + "received from %s on %s", + __FUNCTION__, icp->icmp6_code, + inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, + INET6_ADDRSTRLEN), + if_indextoname(pi->ipi6_ifindex, ifnamebuf)); + return; + } + if (i < sizeof(struct nd_router_solicit)) { + syslog(LOG_NOTICE, + "<%s> RS from %s on %s does not have enough " + "length (len = %d)", + __FUNCTION__, + inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, + INET6_ADDRSTRLEN), + if_indextoname(pi->ipi6_ifindex, ifnamebuf), i); + return; + } rs_input(i, (struct nd_router_solicit *)icp, pi, &from); break; case ND_ROUTER_ADVERT: - /* hop limit verification - RFC-2461 6.1.1 */ + /* + * Message verification - RFC-2461 6.1.2 + * XXX: there's a same dilemma as above... + */ if (*hlimp != 255) { syslog(LOG_NOTICE, - "<%s> invalid hop limit(%d) " + "<%s> RA with invalid hop limit(%d) " "received from %s on %s", __FUNCTION__, *hlimp, inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, @@ -521,6 +675,26 @@ rtadvd_input(skt) if_indextoname(pi->ipi6_ifindex, ifnamebuf)); return; } + if (icp->icmp6_code) { + syslog(LOG_NOTICE, + "<%s> RA with invalid ICMP6 code(%d) " + "received from %s on %s", + __FUNCTION__, icp->icmp6_code, + inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, + INET6_ADDRSTRLEN), + if_indextoname(pi->ipi6_ifindex, ifnamebuf)); + return; + } + if (i < sizeof(struct nd_router_advert)) { + syslog(LOG_NOTICE, + "<%s> RA from %s on %s does not have enough " + "length (len = %d)", + __FUNCTION__, + inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, + INET6_ADDRSTRLEN), + if_indextoname(pi->ipi6_ifindex, ifnamebuf), i); + return; + } ra_input(i, (struct nd_router_advert *)icp, pi, &from); break; case ICMP6_ROUTER_RENUMBERING: @@ -608,6 +782,8 @@ rs_input(int len, struct nd_router_solicit *rs, goto done; } + ra->rsinput++; /* increment statistics */ + /* * Decide whether to send RA according to the rate-limit * consideration. @@ -615,6 +791,19 @@ rs_input(int len, struct nd_router_solicit *rs, { long delay; /* must not be greater than 1000000 */ struct timeval interval, now, min_delay, tm_tmp, *rest; + struct soliciter *sol; + + /* + * record sockaddr waiting for RA, if possible + */ + sol = (struct soliciter *)malloc(sizeof(*sol)); + if (sol) { + sol->addr = *from; + /*XXX RFC2553 need clarification on flowinfo */ + sol->addr.sin6_flowinfo = 0; + sol->next = ra->soliciter; + ra->soliciter = sol->next; + } /* * If there is already a waiting RS packet, don't @@ -658,7 +847,7 @@ rs_input(int len, struct nd_router_solicit *rs, TIMEVAL_ADD(&min_delay, &interval, &interval); } rtadvd_set_timer(&interval, ra->timer); - goto done; + goto done; } done: @@ -675,6 +864,7 @@ ra_input(int len, struct nd_router_advert *ra, union nd_opts ndopts; char *on_off[] = {"OFF", "ON"}; u_int32_t reachabletime, retranstimer, mtu; + int inconsistent = 0; syslog(LOG_DEBUG, "<%s> RA received from %s on %s", @@ -682,13 +872,13 @@ ra_input(int len, struct nd_router_advert *ra, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), if_indextoname(pi->ipi6_ifindex, ifnamebuf)); - + /* ND option check */ memset(&ndopts, 0, sizeof(ndopts)); if (nd6_options((struct nd_opt_hdr *)(ra + 1), len - sizeof(struct nd_router_advert), &ndopts, - NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU)) { + NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU)) { syslog(LOG_ERR, "<%s> ND option check failed for an RA from %s on %s", __FUNCTION__, @@ -711,6 +901,8 @@ ra_input(int len, struct nd_router_advert *ra, if_indextoname(pi->ipi6_ifindex, ifnamebuf)); goto done; } + rai->rainput++; /* increment statistics */ + /* Cur Hop Limit value */ if (ra->nd_ra_curhoplimit && rai->hoplimit && ra->nd_ra_curhoplimit != rai->hoplimit) { @@ -723,6 +915,7 @@ ra_input(int len, struct nd_router_advert *ra, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), rai->hoplimit); + inconsistent++; } /* M flag */ if ((ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) != @@ -736,6 +929,7 @@ ra_input(int len, struct nd_router_advert *ra, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), on_off[rai->managedflg]); + inconsistent++; } /* O flag */ if ((ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) != @@ -749,6 +943,7 @@ ra_input(int len, struct nd_router_advert *ra, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), on_off[rai->otherflg]); + inconsistent++; } /* Reachable Time */ reachabletime = ntohl(ra->nd_ra_reachable); @@ -763,6 +958,7 @@ ra_input(int len, struct nd_router_advert *ra, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), rai->reachabletime); + inconsistent++; } /* Retrans Timer */ retranstimer = ntohl(ra->nd_ra_retransmit); @@ -777,6 +973,7 @@ ra_input(int len, struct nd_router_advert *ra, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), rai->retranstimer); + inconsistent++; } /* Values in the MTU options */ if (ndopts.nd_opts_mtu) { @@ -790,34 +987,50 @@ ra_input(int len, struct nd_router_advert *ra, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), rai->linkmtu); + inconsistent++; } } /* Preferred and Valid Lifetimes for prefixes */ { struct nd_optlist *optp = ndopts.nd_opts_list; - - if (ndopts.nd_opts_pi) - prefix_check(ndopts.nd_opts_pi, rai, from); + + if (ndopts.nd_opts_pi) { + if (prefix_check(ndopts.nd_opts_pi, rai, from)) + inconsistent++; + } while (optp) { - prefix_check((struct nd_opt_prefix_info *)optp->opt, - rai, from); + if (prefix_check((struct nd_opt_prefix_info *)optp->opt, + rai, from)) + inconsistent++; optp = optp->next; } } + if (inconsistent) { + printf("RA input %d inconsistents\n", inconsistent); + rai->rainconsistent++; + } + done: free_ndopts(&ndopts); return; } -static void +/* return a non-zero value if the received prefix is inconsitent with ours */ +static int prefix_check(struct nd_opt_prefix_info *pinfo, struct rainfo *rai, struct sockaddr_in6 *from) { u_int32_t preferred_time, valid_time; struct prefix *pp; + int inconsistent = 0; u_char ntopbuf[INET6_ADDRSTRLEN], prefixbuf[INET6_ADDRSTRLEN]; +#if 0 /* impossible */ + if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION) + return(0); +#endif + /* * log if the adveritsed prefix has link-local scope(sanity check?) */ @@ -845,11 +1058,11 @@ prefix_check(struct nd_opt_prefix_info *pinfo, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), rai->ifname); - return; + return(0); } preferred_time = ntohl(pinfo->nd_opt_pi_preferred_time); - if (preferred_time != pp->preflifetime) + if (preferred_time != pp->preflifetime) { syslog(LOG_WARNING, "<%s> prefeerred lifetime for %s/%d" " inconsistent on %s:" @@ -862,9 +1075,11 @@ prefix_check(struct nd_opt_prefix_info *pinfo, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), pp->preflifetime); + inconsistent++; + } valid_time = ntohl(pinfo->nd_opt_pi_valid_time); - if (valid_time != pp->validlifetime) + if (valid_time != pp->validlifetime) { syslog(LOG_WARNING, "<%s> valid lifetime for %s/%d" " inconsistent on %s:" @@ -877,6 +1092,10 @@ prefix_check(struct nd_opt_prefix_info *pinfo, inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, INET6_ADDRSTRLEN), pp->validlifetime); + inconsistent++; + } + + return(inconsistent); } struct prefix * @@ -993,19 +1212,32 @@ free_ndopts(union nd_opts *ndopts) } void -sock_open(int *sockp, int is_rr, char *policy) +sock_open() { struct icmp6_filter filt; struct ipv6_mreq mreq; struct rainfo *ra = ralist; int on; - char *rtr_str; /* XXX: should be max MTU attached to the node */ static u_char answer[1500]; - static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int))]; - if ((*sockp = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { + rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + rcvcmsgbuf = (u_char *)malloc(rcvcmsgbuflen); + if (rcvcmsgbuf == NULL) { + syslog(LOG_ERR, "<%s> not enough core", __FUNCTION__); + exit(1); + } + + sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + sndcmsgbuf = (u_char *)malloc(sndcmsgbuflen); + if (sndcmsgbuf == NULL) { + syslog(LOG_ERR, "<%s> not enough core", __FUNCTION__); + exit(1); + } + + if ((sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__, strerror(errno)); exit(1); @@ -1013,77 +1245,73 @@ sock_open(int *sockp, int is_rr, char *policy) /* specify to tell receiving interface */ on = 1; - if (setsockopt(*sockp, IPPROTO_IPV6, IPV6_PKTINFO, &on, +#ifdef IPV6_RECVPKTINFO + if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, + sizeof(on)) < 0) { + syslog(LOG_ERR, "<%s> IPV6_RECVPKTINFO: %s", + __FUNCTION__, strerror(errno)); + exit(1); + } +#else /* old adv. API */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on)) < 0) { syslog(LOG_ERR, "<%s> IPV6_PKTINFO: %s", __FUNCTION__, strerror(errno)); exit(1); } +#endif on = 1; /* specify to tell value of hoplimit field of received IP6 hdr */ - if (setsockopt(*sockp, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, +#ifdef IPV6_RECVHOPLIMIT + if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, + sizeof(on)) < 0) { + syslog(LOG_ERR, "<%s> IPV6_RECVHOPLIMIT: %s", + __FUNCTION__, strerror(errno)); + exit(1); + } +#else /* old adv. API */ + if (setsockopt(sock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on)) < 0) { syslog(LOG_ERR, "<%s> IPV6_HOPLIMIT: %s", __FUNCTION__, strerror(errno)); exit(1); } +#endif ICMP6_FILTER_SETBLOCKALL(&filt); - if (is_rr) + ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filt); + ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt); + if (accept_rr) ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt); - else { - ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filt); - ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt); - } - if (setsockopt(*sockp, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, + if (setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)) < 0) { syslog(LOG_ERR, "<%s> IICMP6_FILTER: %s", __FUNCTION__, strerror(errno)); exit(1); } - -#ifdef IPSEC -#ifdef IPSEC_POLICY_IPSEC - if (is_rr && policy != NULL) { - char *buf; - - buf = ipsec_set_policy(policy, strlen(policy)); - if (buf == NULL) - errx(EX_CONFIG, ipsec_strerror()); - if (setsockopt(*sockp, IPPROTO_IPV6, IPV6_IPSEC_POLICY, - buf, ipsec_get_policylen(buf)) < 0) - err(EX_CONFIG, "ipsec policy cannot be configured"); - free(buf); - } -#endif /*IPSEC_POLICY_IPSEC*/ -#endif /*IPSEC*/ - /* * join all routers multicast address on each advertising interface. */ - rtr_str = is_rr ? ALLSITEROUTERS : ALLROUTERS; - if (inet_pton(AF_INET6, rtr_str, &mreq.ipv6mr_multiaddr.s6_addr) + if (inet_pton(AF_INET6, ALLROUTERS, &mreq.ipv6mr_multiaddr.s6_addr) != 1) { - syslog(LOG_ERR, "<%s> inet_pton for %s failed(library bug?)", - __FUNCTION__, rtr_str); + syslog(LOG_ERR, "<%s> inet_pton failed(library bug?)", + __FUNCTION__); exit(1); } while(ra) { mreq.ipv6mr_interface = ra->ifindex; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, + if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, + &mreq, sizeof(mreq)) < 0) { - syslog(LOG_ERR, "<%s> IPV6_JOIN_GROUP for %s on" - "%s: %s", __FUNCTION__, - rtr_str, ra->ifname, strerror(errno)); + syslog(LOG_ERR, "<%s> IPV6_JOIN_GROUP on %s: %s", + __FUNCTION__, ra->ifname, strerror(errno)); exit(1); } ra = ra->next; } - if (is_rr) /* msghdrs should have been alreadey initialized. */ - return; - + /* initialize msghdr for receiving packets */ rcviov[0].iov_base = (caddr_t)answer; rcviov[0].iov_len = sizeof(answer); @@ -1092,15 +1320,15 @@ sock_open(int *sockp, int is_rr, char *policy) rcvmhdr.msg_iov = rcviov; rcvmhdr.msg_iovlen = 1; rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; - rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf); + rcvmhdr.msg_controllen = rcvcmsgbuflen; /* 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); - + sndmhdr.msg_controllen = sndcmsgbuflen; + return; } @@ -1133,9 +1361,15 @@ ra_output(rainfo) struct rainfo *rainfo; { int i; - struct cmsghdr *cm; struct in6_pktinfo *pi; + struct soliciter *sol, *nextsol; + + if ((iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) { + syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA", + __FUNCTION__, rainfo->ifname); + return; + } sndmhdr.msg_name = (caddr_t)&sin6_allnodes; sndmhdr.msg_iov[0].iov_base = (caddr_t)rainfo->ra_data; @@ -1163,20 +1397,48 @@ struct rainfo *rainfo; syslog(LOG_DEBUG, "<%s> send RA on %s, # of waitings = %d", - __FUNCTION__, rainfo->ifname, rainfo->waiting); + __FUNCTION__, rainfo->ifname, rainfo->waiting); i = sendmsg(sock, &sndmhdr, 0); if (i < 0 || i != rainfo->ra_datalen) { if (i < 0) { - syslog(LOG_ERR, "<%s> sendmsg to %s: %s", - __FUNCTION__, rainfo->ifname, strerror(errno)); + syslog(LOG_ERR, "<%s> sendmsg on %s: %s", + __FUNCTION__, rainfo->ifname, + strerror(errno)); } } + /* + * unicast advertisements + * XXX commented out. reason: though spec does not forbit it, unicast + * advert does not really help + */ + for (sol = rainfo->soliciter; sol; sol = nextsol) { + nextsol = sol->next; + +#if 0 + sndmhdr.msg_name = (caddr_t)&sol->addr; + i = sendmsg(sock, &sndmhdr, 0); + if (i < 0 || i != rainfo->ra_datalen) { + if (i < 0) { + syslog(LOG_ERR, + "<%s> unicast sendmsg on %s: %s", + __FUNCTION__, rainfo->ifname, + strerror(errno)); + } + } +#endif + + sol->next = NULL; + free(sol); + } + rainfo->soliciter = NULL; + /* update counter */ if (rainfo->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS) rainfo->initcounter++; + rainfo->raoutput++; /* update timestamp */ gettimeofday(&rainfo->lastsent, NULL); @@ -1199,11 +1461,7 @@ ra_timeout(void *data) "<%s> RA timer on %s is expired", __FUNCTION__, rai->ifname); - if (iflist[rai->ifindex]->ifm_flags & IFF_UP) - ra_output(rai); - else - syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA", - __FUNCTION__, rai->ifname); + ra_output(rai); } /* update RA timer */ @@ -1219,7 +1477,7 @@ ra_timer_update(void *data, struct timeval *tm) * between the interface's configured MinRtrAdvInterval and * MaxRtrAdvInterval(discovery-v2-02 6.2.4). */ - interval = rai->mininterval; + interval = rai->mininterval; interval += random() % (rai->maxinterval - rai->mininterval); /* @@ -1238,7 +1496,8 @@ ra_timer_update(void *data, struct timeval *tm) syslog(LOG_DEBUG, "<%s> RA timer on %s is set to %ld:%ld", - __FUNCTION__, rai->ifname, tm->tv_sec, tm->tv_usec); + __FUNCTION__, rai->ifname, + (long int)tm->tv_sec, (long int)tm->tv_usec); return; } diff --git a/usr.sbin/rtadvd/rtadvd.conf b/usr.sbin/rtadvd/rtadvd.conf index f40a6503df8b5..bdac4f1040276 100644 --- a/usr.sbin/rtadvd/rtadvd.conf +++ b/usr.sbin/rtadvd/rtadvd.conf @@ -1,14 +1,29 @@ # $FreeBSD$ + # # common definitions. # -default:\ - :chlim#64:raflags#0:rltime#1800:rtime#30000:retrans#1000:\ - :pinfoflags#192:vltime#3600000:pltime#3600000:mtu#1500: -ether:\ - :mtu#1500:tc=default: +# Note: All of the following parameters have default values defined +# in specifications, and hence you usually do not have to set them +# by hand unless you need special non-default values. # -# interfaces. -# -ef0:\ - :addrs#1:addr="fec0:0:0:1000::":prefixlen#64:tc=ether: +# You even do not need to create the configuration file. rtadvd +# would usually work well without a configuration file. +# See also: rtadvd(8) + +#default:\ +# :chlim#64:raflags#0:rltime#1800:rtime#30000:retrans#1000:\ +# :pinfoflags#192:vltime#3600000:pltime#3600000:mtu#1500: +#ether:\ +# :mtu#1500:tc=default: + +# per-interface definitions. +# Mainly IPv6 prefixes are configured in this part. However, rtadvd +# automatically learns appropriate prefixes from the kernel's routing +# table and advertises the prefixes, so you don't have to configure +# this part, either. +# If you don't want the automatic advertisement, invoke rtadvd with +# the -s option and configure this part by hand. + +#ef0:\ +# :addrs#1:addr="3ffe:501:4819:1000::":prefixlen#64:tc=ether: diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5 index 5d1fed2ae4f2b..cc0b63d9e8ce3 100644 --- a/usr.sbin/rtadvd/rtadvd.conf.5 +++ b/usr.sbin/rtadvd/rtadvd.conf.5 @@ -1,3 +1,5 @@ +.\" $KAME: rtadvd.conf.5,v 1.5 2000/05/22 22:22:56 itojun Exp $ +.\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. .\" @@ -25,49 +27,51 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: rtadvd.conf.5,v 1.1.1.1 1999/08/08 23:31:42 itojun Exp $ -.\" $FreeBSD$ +.\" $FreeBSD$ .\" .Dd May 17, 1998 .Dt RTADVD.CONF 5 -.Os KAME +.Os .Sh NAME .Nm rtadvd.conf .Nd config file for router advertisement daemon .Sh DESCRIPTION -The file describes how the router advertisement packet must be constructed +This file describes how the router advertisement packet must be constructed for each of the interfaces. .Pp -It obeys famous +It obeys the famous .Xr termcap 5 file format. Each line in the file describes a network interface. Fields are separated by a colon -.Po -.Dq \&: -.Pc , +.Pq Sq \&: , and each field contains one capability description. -Lines may be concatenated by \e character. -The comment marker is `#' character. +Lines may be concatenated by +.Sq \e +character. +The comment marker is the +.Sq \# +character. .Pp .Sh CAPABILITIES Capabilities describe the value to be filled into ICMPv6 router -advertisement message and to control +advertisement messages and to control .Xr rtadvd 8 behavior. Therefore, you are encouraged to read IETF neighbor discovery documents -if you would like to modify sample configuration file. +if you would like to modify the sample configuration file. .Pp Note that almost all items have default values. If you omit an item, the default value of the item will be used. .Pp -There are two items to control interval of sending router advertisements. +There are two items which control the interval of sending router advertisements. .Bl -tag -width indent .It Cm \&maxinterval (num) The maximum time allowed between sending unsolicited multicast router advertisements .Pq unit: seconds . -The default value is 600. Its value must be no less than 4 seconds +The default value is 600. +Its value must be no less than 4 seconds and no greater than 1800 seconds. .It Cm \&mininterval (num) The minimum time allowed between sending unsolicited multicast @@ -130,8 +134,8 @@ If its value is more than 1, you must specify the index of the prefix for each item below. Indices vary from 0 to N-1, where N is the value of -.Ic addrs. -Each index shall follows the name of each item, e.g. +.Ic addrs . +Each index shall follow the name of each item, e.g., .Dq prefixlen2 . .It Cm \&prefixlen (num) Prefix length field. @@ -148,7 +152,7 @@ and Bit 6 .Li 0x40 .Pc means Autonomous address-configuration flag bit. -The default value is 0xc0, i.e. both bits are set. +The default value is 0xc0, i.e., both bits are set. .It Cm \&addr (str) The address filled into Prefix field. Since @@ -177,7 +181,8 @@ which will be attached to router advertisement header. .It Cm \&mtu (num or str) MTU (maximum transmission unit) field. If 0 is specified, it means that the option will not be included. -The default value is 0. If the special string +The default value is 0. +If the special string .Dq auto is specified for this item, MTU option will be included and its value will be set to the interface MTU automatically. @@ -202,6 +207,26 @@ will not attach source link-layer address option to router advertisement packets. .El .Pp +The following item controls ICMPV6 home agent information option, +which was defined with mobile IPv6 support. +It will be attached to router advertisement header just like other options do. +.Bl -tag -width indent +.It Cm \&hapref +(num) Specifies home agent preference. +If set to non-zero, +.Cm \&hatime +must be present as well. +.It Cm \&hatime +(num) Specifies home agent lifetime. +.El +.Pp +When mobile IPv6 support is turned on for +.Xr rtadvd 8 , +advertisement interval option will be attached to router advertisement +packet, by configuring +.Cm \&maxinterval +explicitly. +.Pp You can also refer one line from another by using .Cm tc capability. diff --git a/usr.sbin/rtadvd/rtadvd.h b/usr.sbin/rtadvd/rtadvd.h index 92fbcdf02213f..40beb1d87f973 100644 --- a/usr.sbin/rtadvd/rtadvd.h +++ b/usr.sbin/rtadvd/rtadvd.h @@ -1,7 +1,9 @@ +/* $KAME: rtadvd.h,v 1.8 2000/05/16 13:34:14 itojun Exp $ */ + /* * 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: @@ -13,7 +15,7 @@ * 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 @@ -29,43 +31,64 @@ * $FreeBSD$ */ -#define ALLNODES "ff02::1" -#define ALLROUTERS "ff02::2" -#define ALLSITEROUTERS "ff05::2" -#define ANY "::" -#define RTSOLLEN 8 +#define ALLNODES "ff02::1" +#define ALLROUTERS "ff02::2" +#define ANY "::" +#define RTSOLLEN 8 /* protocol constants and default values */ -#define DEF_MAXRTRADVINTERVAL 600 -#define DEF_ADVLINKMTU 0 -#define DEF_ADVREACHABLETIME 0 -#define DEF_ADVRETRANSTIMER 0 -#define DEF_ADVCURHOPLIMIT 64 -#define DEF_ADVVALIDLIFETIME 2592000 -#define DEF_ADVPREFERREDLIFETIME 604800 +#define DEF_MAXRTRADVINTERVAL 600 +#define DEF_ADVLINKMTU 0 +#define DEF_ADVREACHABLETIME 0 +#define DEF_ADVRETRANSTIMER 0 +#define DEF_ADVCURHOPLIMIT 64 +#define DEF_ADVVALIDLIFETIME 2592000 +#define DEF_ADVPREFERREDLIFETIME 604800 + +/*XXX int-to-double comparison for INTERVAL items */ +#ifndef MIP6 +#define mobileip6 0 +#endif + +#define MAXROUTERLIFETIME 9000 +#define MIN_MAXINTERVAL (mobileip6 ? 1.5 : 4.0) +#define MAX_MAXINTERVAL 1800 +#define MIN_MININTERVAL (mobileip6 ? 0.5 : 3) +#define MAXREACHABLETIME 3600000 + +#ifndef MIP6 +#undef miobileip6 +#endif -#define MAXROUTERLIFETIME 9000 -#define MIN_MAXINTERVAL 4 -#define MAX_MAXINTERVAL 1800 -#define MIN_MININTERVAL 3 -#define MAXREACHABLETIME 3600000 +#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16 +#define MAX_INITIAL_RTR_ADVERTISEMENTS 3 +#define MAX_FINAL_RTR_ADVERTISEMENTS 3 +#define MIN_DELAY_BETWEEN_RAS 3 +#define MAX_RA_DELAY_TIME 500000 /* usec */ -#define MAX_INITIAL_RTR_ADVERT_INTERVAL 16 -#define MAX_INITIAL_RTR_ADVERTISEMENTS 3 -#define MAX_FINAL_RTR_ADVERTISEMENTS 3 -#define MIN_DELAY_BETWEEN_RAS 3 -#define MAX_RA_DELAY_TIME 500000 /* usec */ +#define PREFIX_FROM_KERNEL 1 +#define PREFIX_FROM_CONFIG 2 +#define PREFIX_FROM_DYNAMIC 3 struct prefix { - struct prefix *next; /* forward link */ - struct prefix *prev; /* previous link */ + struct prefix *next; /* forward link */ + struct prefix *prev; /* previous link */ - u_int32_t validlifetime; /* AdvValidLifetime */ - u_int32_t preflifetime; /* AdvPreferredLifetime */ - u_int onlinkflg; /* bool: AdvOnLinkFlag */ - u_int autoconfflg; /* bool: AdvAutonomousFlag */ - int prefixlen; - struct in6_addr prefix; + u_int32_t validlifetime; /* AdvValidLifetime */ + u_int32_t preflifetime; /* AdvPreferredLifetime */ + u_int onlinkflg; /* bool: AdvOnLinkFlag */ + u_int autoconfflg; /* bool: AdvAutonomousFlag */ +#ifdef MIP6 + u_int routeraddr; /* bool: RouterAddress */ +#endif + int prefixlen; + int origin; /* from kernel or cofig */ + struct in6_addr prefix; +}; + +struct soliciter { + struct soliciter *next; + struct sockaddr_in6 addr; }; struct rainfo { @@ -73,35 +96,56 @@ struct rainfo { struct rainfo *next; /* timer related parameters */ - struct rtadvd_timer *timer; - int initcounter; /* counter for the first few advertisements */ - struct timeval lastsent; /* timestamp when the lates RA was sent */ - int waiting; /* number of RS waiting for RA */ + struct rtadvd_timer *timer; + int initcounter; /* counter for the first few advertisements */ + struct timeval lastsent; /* timestamp when the latest RA was sent */ + int waiting; /* number of RS waiting for RA */ /* interface information */ int ifindex; int advlinkopt; /* bool: whether include link-layer addr opt */ - struct sockaddr_dl *sdl; + struct sockaddr_dl *sdl; char ifname[16]; int phymtu; /* mtu of the physical interface */ /* Router configuration variables */ - u_short lifetime; /* AdvDefaultLifetime */ + u_short lifetime; /* AdvDefaultLifetime */ u_int maxinterval; /* MaxRtrAdvInterval */ u_int mininterval; /* MinRtrAdvInterval */ int managedflg; /* AdvManagedFlag */ int otherflg; /* AdvOtherConfigFlag */ - u_int32_t linkmtu; /* AdvLinkMTU */ - u_int32_t reachabletime; /* AdvReachableTime */ - u_int32_t retranstimer; /* AdvRetransTimer */ +#ifdef MIP6 + int haflg; /* HAFlag */ +#endif + u_int32_t linkmtu; /* AdvLinkMTU */ + u_int32_t reachabletime; /* AdvReachableTime */ + u_int32_t retranstimer; /* AdvRetransTimer */ u_int hoplimit; /* AdvCurHopLimit */ - struct prefix prefix; /* AdvPrefixList(link head) */ + struct prefix prefix; /* AdvPrefixList(link head) */ int pfxs; /* number of prefixes */ +#ifdef MIP6 + u_short hapref; /* Home Agent Preference */ + u_short hatime; /* Home Agent Lifetime */ +#endif + /* actual RA packet data and its length */ - size_t ra_datalen; - u_char *ra_data; + size_t ra_datalen; + u_char *ra_data; + + /* statistics */ + u_quad_t raoutput; /* number of RAs sent */ + u_quad_t rainput; /* number of RAs received */ + u_quad_t rainconsistent; /* number of RAs inconsistent with ours */ + u_quad_t rsinput; /* number of RSs received */ + + /* info about soliciter */ + struct soliciter *soliciter; /* recent solication source */ }; -void ra_timeout __P((void *)); -void ra_timer_update __P((void *, struct timeval *)); +void ra_timeout __P((void *)); +void ra_timer_update __P((void *, struct timeval *)); + +#ifdef MIP6 +extern int mobileip6; +#endif diff --git a/usr.sbin/rtadvd/timer.c b/usr.sbin/rtadvd/timer.c index f93968a3be0eb..d03eddd53eb12 100644 --- a/usr.sbin/rtadvd/timer.c +++ b/usr.sbin/rtadvd/timer.c @@ -1,7 +1,9 @@ +/* $KAME: timer.c,v 1.3 2000/05/22 22:23:07 itojun Exp $ */ + /* * 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: @@ -13,7 +15,7 @@ * 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 @@ -35,14 +37,16 @@ #include <syslog.h> #include <stdlib.h> #include <string.h> -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__OpenBSD__) #include <search.h> #endif #include "timer.h" static struct rtadvd_timer timer_head; -#define MILLION 1000000 +#define MILLION 1000000 +#define TIMEVAL_EQUAL(t1,t2) ((t1)->tv_sec == (t2)->tv_sec &&\ + (t1)->tv_usec == (t2)->tv_usec) static struct timeval tm_max = {0x7fffffff, 0x7fffffff}; @@ -93,6 +97,14 @@ rtadvd_add_timer(void (*timeout) __P((void *)), } void +rtadvd_remove_timer(struct rtadvd_timer **timer) +{ + remque(*timer); + free(*timer); + *timer = NULL; +} + +void rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *timer) { struct timeval now; @@ -138,7 +150,11 @@ rtadvd_check_timer() tm = tm->next; } - if (TIMEVAL_LT(timer_head.tm, now)) { + if (TIMEVAL_EQUAL(&tm_max, &timer_head.tm)) { + /* no need to timeout */ + return(NULL); + } + else if (TIMEVAL_LT(timer_head.tm, now)) { /* this may occur when the interval is too small */ returnval.tv_sec = returnval.tv_usec = 0; } diff --git a/usr.sbin/rtadvd/timer.h b/usr.sbin/rtadvd/timer.h index e9f2c35057621..9a97c91c3bbb5 100644 --- a/usr.sbin/rtadvd/timer.h +++ b/usr.sbin/rtadvd/timer.h @@ -1,7 +1,9 @@ +/* $KAME: timer.h,v 1.2 2000/05/16 13:34:14 itojun Exp $ */ + /* * 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: @@ -13,7 +15,7 @@ * 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 @@ -30,34 +32,35 @@ */ /* a < b */ -#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\ +#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) ||\ +#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\ (((a).tv_sec == (b).tv_sec) &&\ ((a).tv_usec <= (b).tv_usec))) struct rtadvd_timer { - struct rtadvd_timer *next; - struct rtadvd_timer *prev; - struct rainfo *rai; - struct timeval tm; + struct rtadvd_timer *next; + struct rtadvd_timer *prev; + struct rainfo *rai; + struct timeval tm; - void (*expire) __P((void *)); /* expiration function */ - void *expire_data; - void (*update) __P((void *, struct timeval *)); /* update function */ - void *update_data; + void (*expire) __P((void *)); /* expiration function */ + void *expire_data; + void (*update) __P((void *, struct timeval *)); /* update function */ + void *update_data; }; -void rtadvd_timer_init __P((void)); -struct rtadvd_timer *rtadvd_add_timer __P((void (*) __P((void *)), +void rtadvd_timer_init __P((void)); +struct rtadvd_timer *rtadvd_add_timer __P((void (*) __P((void *)), void (*) __P((void *, struct timeval *)), void *, void *)); -void rtadvd_set_timer __P((struct timeval *, struct rtadvd_timer *)); -struct timeval * rtadvd_check_timer __P((void)); -struct timeval * rtadvd_timer_rest __P((struct rtadvd_timer *)); -void TIMEVAL_ADD __P((struct timeval *, struct timeval *, - struct timeval *)); -void TIMEVAL_SUB __P((struct timeval *, struct timeval *, - struct timeval *)); +void rtadvd_set_timer __P((struct timeval *, struct rtadvd_timer *)); +void rtadvd_remove_timer __P((struct rtadvd_timer **)); +struct timeval * rtadvd_check_timer __P((void)); +struct timeval * rtadvd_timer_rest __P((struct rtadvd_timer *)); +void TIMEVAL_ADD __P((struct timeval *, struct timeval *, + struct timeval *)); +void TIMEVAL_SUB __P((struct timeval *, struct timeval *, + struct timeval *)); diff --git a/usr.sbin/rtsold/Makefile b/usr.sbin/rtsold/Makefile index e348b27d06ecf..2790059e80e92 100644 --- a/usr.sbin/rtsold/Makefile +++ b/usr.sbin/rtsold/Makefile @@ -15,9 +15,9 @@ PROG= rtsold SRCS= rtsold.c rtsol.c if.c probe.c dump.c -CFLAGS+=-DINET6 -LDADD+= -lkvm -DPADD+= ${LIBKVM} +CFLAGS+=-DINET6 -DHAVE_GETIFADDRS +LDADD= -lkvm +DPADD= ${LIBKVM} MAN8= rtsold.8 MLINKS= rtsold.8 rtsol.8 diff --git a/usr.sbin/rtsold/dump.c b/usr.sbin/rtsold/dump.c index 15877210069cb..43badd5e1722b 100644 --- a/usr.sbin/rtsold/dump.c +++ b/usr.sbin/rtsold/dump.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -31,7 +31,9 @@ #include <sys/types.h> #include <sys/time.h> +#include <sys/socket.h> +#include <net/if.h> #include <netinet/in.h> #include <netinet/icmp6.h> @@ -47,6 +49,7 @@ static FILE *fp; extern struct ifinfo *iflist; +static void dump_interface_status __P((void)); static char *sec2str __P((time_t)); char *ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"}; diff --git a/usr.sbin/rtsold/if.c b/usr.sbin/rtsold/if.c index 66aaa554fe820..6bf81052c4bdc 100644 --- a/usr.sbin/rtsold/if.c +++ b/usr.sbin/rtsold/if.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -35,12 +35,23 @@ #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> -#include <net/ethernet.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> @@ -53,25 +64,27 @@ #include <string.h> #include <fcntl.h> #include <errno.h> -#include <kvm.h> -#include <nlist.h> #include <limits.h> +#ifdef HAVE_GETIFADDRS +#include <ifaddrs.h> +#endif #include "rtsold.h" +extern int rssock; static int ifsock; -static int getifa __P((char *name, struct in6_ifaddr *ifap)); +static int get_llflag __P((const char *name)); +#ifndef HAVE_GETIFADDRS +static unsigned int if_maxindex __P((void)); +#endif 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); - } + ifsock = rssock; return(0); } @@ -80,7 +93,7 @@ int interface_up(char *name) { struct ifreq ifr; - struct in6_ifaddr ifa; + int llflag; strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); @@ -100,24 +113,24 @@ interface_up(char *name) warnmsg(LOG_DEBUG, __FUNCTION__, "checking if %s is ready...", name); - if (getifa(name, &ifa) < 0) { + llflag = get_llflag(name); + if (llflag < 0) { warnmsg(LOG_WARNING, __FUNCTION__, - "getifa() failed, anyway I'll try"); + "get_llflag() failed, anyway I'll try"); return 0; } - if (!(ifa.ia6_flags & IN6_IFF_NOTREADY)) { + if (!(llflag & IN6_IFF_NOTREADY)) { warnmsg(LOG_DEBUG, __FUNCTION__, "%s is ready", name); return(0); - } - else { - if (ifa.ia6_flags & IN6_IFF_TENTATIVE) { + } else { + if (llflag & IN6_IFF_TENTATIVE) { warnmsg(LOG_DEBUG, __FUNCTION__, "%s is tentative", name); return IFS_TENTATIVE; } - if (ifa.ia6_flags & IN6_IFF_DUPLICATED) + if (llflag & IN6_IFF_DUPLICATED) warnmsg(LOG_DEBUG, __FUNCTION__, "%s is duplicated", name); return -1; @@ -130,7 +143,7 @@ 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)); @@ -188,14 +201,14 @@ interface_status(struct ifinfo *ifinfo) return(1); } -#define ROUNDUP(a, size) \ +#define ROUNDUP(a, size) \ (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) -#define NEXT_SA(ap) (ap) = (struct sockaddr *) \ +#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)) +#define ROUNDUP8(a) (1 + (((a) - 1) | 7)) int lladdropt_length(struct sockaddr_dl *sdl) @@ -258,6 +271,8 @@ if_nametosdl(char *name) if ((sa = rti_info[RTAX_IFP]) != NULL) { if (sa->sa_family == AF_LINK) { sdl = (struct sockaddr_dl *)sa; + if (strlen(name) != sdl->sdl_nlen) + continue; /* not same len */ if (strncmp(&sdl->sdl_data[0], name, sdl->sdl_nlen) == 0) { @@ -297,91 +312,141 @@ getinet6sysctl(int code) /*------------------------------------------------------------*/ -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; \ - } \ - } - +/* get ia6_flags for link-local addr on if. returns -1 on error. */ static int -getifa(char *name, struct in6_ifaddr *ifap) +get_llflag(const char *name) { - u_short index; - kvm_t *kvmd = NULL; - char buf[_POSIX2_LINE_MAX]; - struct ifnet *ifp; - struct ifnet ifnet; - struct in6_ifaddr *ifa; +#ifdef HAVE_GETIFADDRS + struct ifaddrs *ifap, *ifa; + struct in6_ifreq ifr6; + struct sockaddr_in6 *sin6; + int s; - if (!ifap) + if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, "socket(SOCK_DGRAM): %s", + strerror(errno)); 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 (getifaddrs(&ifap) != 0) { + warnmsg(LOG_ERR, __FUNCTION__, "etifaddrs: %s", + strerror(errno)); + exit(1); } - if (kvm_nlist(kvmd, nl) < 0) { - warnmsg(LOG_ERR, __FUNCTION__, "kvm_nlist failed"); - goto bad; + + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (strlen(ifa->ifa_name) != strlen(name) + || strncmp(ifa->ifa_name, name, strlen(name)) != 0) + continue; + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; + if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + continue; + + memset(&ifr6, 0, sizeof(ifr6)); + strcpy(ifr6.ifr_name, name); + memcpy(&ifr6.ifr_ifru.ifru_addr, sin6, sin6->sin6_len); + if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, + "ioctl(SIOCGIFAFLAG_IN6): %s", strerror(errno)); + exit(1); + } + + freeifaddrs(ifap); + close(s); + return ifr6.ifr_ifru.ifru_flags6; } - if (nl[N_IFNET].n_value == 0) { - warnmsg(LOG_ERR, __FUNCTION__, "symbol \"%s\" not found", - nl[N_IFNET].n_name); - goto bad; + + freeifaddrs(ifap); + close(s); + return -1; +#else + int s; + unsigned int maxif; + struct ifreq *iflist; + struct ifconf ifconf; + struct ifreq *ifr, *ifr_end; + struct sockaddr_in6 *sin6; + struct in6_ifreq ifr6; + + maxif = if_maxindex() + 1; + iflist = (struct ifreq *)malloc(maxif * BUFSIZ); /* XXX */ + if (iflist == NULL) { + warnmsg(LOG_ERR, __FUNCTION__, "not enough core"); + exit(1); } - KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *); - while (ifp) { - KREAD(ifp, &ifnet, struct ifnet); - if (ifnet.if_index == index) - break; - ifp = TAILQ_NEXT(&ifnet, if_link); + if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, "socket(SOCK_DGRAM): %s", + strerror(errno)); + exit(1); } - if (!ifp) { - warnmsg(LOG_ERR, __FUNCTION__, "interface \"%s\" not found", - name); - goto bad; + memset(&ifconf, 0, sizeof(ifconf)); + ifconf.ifc_req = iflist; + ifconf.ifc_len = maxif * BUFSIZ; /* XXX */ + if (ioctl(s, SIOCGIFCONF, &ifconf) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, "ioctl(SIOCGIFCONF): %s", + strerror(errno)); + exit(1); } - ifa = (struct in6_ifaddr *)TAILQ_FIRST(&ifnet.if_addrhead); - 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; + /* Look for this interface in the list */ + ifr_end = (struct ifreq *) (ifconf.ifc_buf + ifconf.ifc_len); + for (ifr = ifconf.ifc_req; + ifr < ifr_end; + ifr = (struct ifreq *) ((char *) &ifr->ifr_addr + + ifr->ifr_addr.sa_len)) { + if (strlen(ifr->ifr_name) != strlen(name) + || strncmp(ifr->ifr_name, name, strlen(name)) != 0) + continue; + if (ifr->ifr_addr.sa_family != AF_INET6) + continue; + sin6 = (struct sockaddr_in6 *)&ifr->ifr_addr; + if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + continue; + + memset(&ifr6, 0, sizeof(ifr6)); + strcpy(ifr6.ifr_name, name); + memcpy(&ifr6.ifr_ifru.ifru_addr, sin6, sin6->sin6_len); + if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, + "ioctl(SIOCGIFAFLAG_IN6): %s", strerror(errno)); + exit(1); } - ifa = (struct in6_ifaddr *) - TAILQ_NEXT((struct ifaddr *)ifap, ifa_link); + free(iflist); + close(s); + return ifr6.ifr_ifru.ifru_flags6; } - warnmsg(LOG_ERR, __FUNCTION__, "no IPv6 link-local address for %s", - name); - bad: - if (kvmd) - kvm_close(kvmd); + free(iflist); + close(s); return -1; +#endif } +#ifndef HAVE_GETIFADDRS +static unsigned int +if_maxindex() +{ + struct if_nameindex *p, *p0; + unsigned int max = 0; + + p0 = if_nameindex(); + for (p = p0; p && p->if_index && p->if_name; p++) { + if (max < p->if_index) + max = p->if_index; + } + if_freenameindex(p0); + return max; +} +#endif + static void get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) { int i; - + for (i = 0; i < RTAX_MAX; i++) { if (addrs & (1 << i)) { rti_info[i] = sa; diff --git a/usr.sbin/rtsold/probe.c b/usr.sbin/rtsold/probe.c index 824baebf062a8..64eabcf814e05 100644 --- a/usr.sbin/rtsold/probe.c +++ b/usr.sbin/rtsold/probe.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -36,7 +36,9 @@ #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> @@ -49,6 +51,7 @@ #include <unistd.h> #include <string.h> #include <syslog.h> +#include <stdlib.h> #include "rtsold.h" @@ -57,11 +60,19 @@ 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))]; + int scmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + static u_char *sndcmsgbuf = NULL; + + if (sndcmsgbuf == NULL && + (sndcmsgbuf = (u_char *)malloc(scmsglen)) == NULL) { + warnmsg(LOG_ERR, __FUNCTION__, "malloc failed"); + return(-1); + } if ((probesock = socket(AF_INET6, SOCK_RAW, IPPROTO_NONE)) < 0) { warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno)); @@ -79,13 +90,13 @@ probe_init() sndmhdr.msg_iov = sndiov; sndmhdr.msg_iovlen = 1; sndmhdr.msg_control = (caddr_t)sndcmsgbuf; - sndmhdr.msg_controllen = sizeof(sndcmsgbuf); + sndmhdr.msg_controllen = scmsglen; return(0); } /* - * Probe if each router in the default router list is still alive. + * Probe if each router in the default router list is still alive. */ void defrouter_probe(int ifindex) diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c index 5b76403da6950..41003ca70804b 100644 --- a/usr.sbin/rtsold/rtsol.c +++ b/usr.sbin/rtsold/rtsol.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -55,7 +55,7 @@ #include <syslog.h> #include "rtsold.h" -#define ALLROUTER "ff02::2" +#define ALLROUTER "ff02::2" static struct msghdr rcvmhdr; static struct msghdr sndmhdr; @@ -63,7 +63,7 @@ static struct iovec rcviov[2]; static struct iovec sndiov[2]; static struct sockaddr_in6 from; -static int rssock; +int rssock; static struct sockaddr_in6 sin6_allrouters = {sizeof(sin6_allrouters), AF_INET6}; @@ -73,11 +73,21 @@ 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))]; + int rcvcmsglen, sndcmsglen; + static u_char *rcvcmsgbuf = NULL, *sndcmsgbuf = NULL; + sndcmsglen = rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + if (rcvcmsgbuf == NULL && (rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) { + warnmsg(LOG_ERR, __FUNCTION__, + "malloc for receive msghdr failed"); + return(-1); + } + if (sndcmsgbuf == NULL && (sndcmsgbuf = malloc(sndcmsglen)) == NULL) { + warnmsg(LOG_ERR, __FUNCTION__, + "malloc for send msghdr failed"); + return(-1); + } memset(&sin6_allrouters, 0, sizeof(struct sockaddr_in6)); if (inet_pton(AF_INET6, ALLROUTER, &sin6_allrouters.sin6_addr.s6_addr) != 1) { @@ -93,21 +103,39 @@ sockopen() /* specify to tell receiving interface */ on = 1; +#ifdef IPV6_RECVPKTINFO + if (setsockopt(rssock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, + sizeof(on)) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, "IPV6_RECVPKTINFO: %s", + strerror(errno)); + exit(1); + } +#else /* old adv. API */ if (setsockopt(rssock, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on)) < 0) { warnmsg(LOG_ERR, __FUNCTION__, "IPV6_PKTINFO: %s", strerror(errno)); exit(1); } +#endif on = 1; /* specify to tell value of hoplimit field of received IP6 hdr */ +#ifdef IPV6_RECVHOPLIMIT + if (setsockopt(rssock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, + sizeof(on)) < 0) { + warnmsg(LOG_ERR, __FUNCTION__, "IPV6_RECVHOPLIMIT: %s", + strerror(errno)); + exit(1); + } +#else /* old adv. API */ if (setsockopt(rssock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on)) < 0) { warnmsg(LOG_ERR, __FUNCTION__, "IPV6_HOPLIMIT: %s", strerror(errno)); exit(1); } +#endif /* specfiy to accept only router advertisements on the socket */ ICMP6_FILTER_SETBLOCKALL(&filt); @@ -127,14 +155,14 @@ sockopen() rcvmhdr.msg_iov = rcviov; rcvmhdr.msg_iovlen = 1; rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; - rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf); + rcvmhdr.msg_controllen = rcvcmsglen; /* 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); + sndmhdr.msg_controllen = sndcmsglen; return(rssock); } diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8 index 90d483ad6a7e0..d1a50b1b65120 100644 --- a/usr.sbin/rtsold/rtsold.8 +++ b/usr.sbin/rtsold/rtsold.8 @@ -1,6 +1,6 @@ .\" 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: @@ -12,7 +12,7 @@ .\" 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 @@ -25,7 +25,7 @@ .\" 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 $ +.\" $Id: rtsold.8,v 1.9 2000/07/04 14:44:38 jinmei Exp $ .\" $FreeBSD$ .\" .Dd May 17, 1998 @@ -53,11 +53,26 @@ If a node (re)attaches to a link, 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 +.Pp +If you invoke the program as +.Nm rtsol , +it will transmit probes from the specified +.Ar interface , +without becoming a daemon. +In other words, +.Nm rtsol +behaves as +.Do +.Nm +.Fl f1 +.Ar interfaces +.Dc . +.Pp Specifically, .Nm sends at most 3 Router Solicitations on an interface after one of the following events: +.Pp .Bl -bullet -compact .It Just after invocation of @@ -66,32 +81,32 @@ 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. +detects such failures by periodically probing to see if the status +of the interface is active or not. +Note that some network cards and drivers do not allow the extraction +of link state. In such cases, .Nm cannot detect the change of the interface status. .It -Every one minute if +Every 60 seconds if the .Fl m -option is specified and +option is specified and the .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 +Default interval for 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. +when they attach to 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 +it refrains 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, @@ -103,7 +118,7 @@ Upon receipt of signal .Dv SIGUSR1 , .Nm will dump the current internal state into -.Pa /var/tmp/rtsold.dump. +.Pa /var/run/rtsold.dump. .\" .Sh OPTIONS .Bl -tag -width indent @@ -134,18 +149,9 @@ periodically sends Router Solicitation on an interface that does not support ioctl. .It Fl 1 Perform only one probe. -Transmit Router Solcitation packet until valid Router Advertisement packet +Transmit Router Solicitation 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. .\" @@ -154,7 +160,7 @@ The program exits with 0 on success, non-zero on failures. .It Pa /var/run/rtsold.pid the pid of the currently running .Nm rtsold . -.It Pa /var/tmp/rtsold.dump +.It Pa /var/run/rtsold.dump dumps internal state on. .El .\" @@ -165,11 +171,22 @@ dumps internal state on. .Sh HISTORY The .Nm -command is based on +command is based on the .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) +.\" +.Sh BUGS +In some operating systems, when a PCMCIA network card is removed +and reinserted, the corresponding interface index is changed. +However, +.Nm +does not assume such changes, and always uses the index that +it got at invocation. As a result, +.Nm +may not work if you reinsert a network card. +In such a case, +.Nm +should be killed and restarted. diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c index 8d5646f54a93c..7259c20436ae4 100644 --- a/usr.sbin/rtsold/rtsold.c +++ b/usr.sbin/rtsold/rtsold.c @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -31,7 +31,9 @@ #include <sys/types.h> #include <sys/time.h> +#include <sys/socket.h> +#include <net/if.h> #include <net/if_dl.h> #include <netinet/in.h> @@ -55,36 +57,39 @@ 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 */ +#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 */ +#define PROBE_INTERVAL 60 /* secondes XXX: should be configurable */ /* utility macros */ /* a < b */ -#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\ +#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) ||\ +#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)) +#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 *dumpfilename = "/var/run/rtsold.dump"; /* XXX: should be configurable */ static char *pidfilename = "/var/run/rtsold.pid"; /* should be configurable */ static int ifconfig __P((char *ifname)); +#if 0 +static int ifreconfig __P((char *ifname)); +#endif 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, @@ -92,7 +97,7 @@ static void TIMEVAL_ADD __P((struct timeval *a, struct timeval *b, static void TIMEVAL_SUB __P((struct timeval *a, struct timeval *b, struct timeval *result)); -static void rtsold_set_dump_file __P(()); +static void rtsold_set_dump_file __P((void)); static void usage __P((char *progname)); int @@ -161,8 +166,10 @@ main(argc, argv) setlogmask(LOG_UPTO(log_upto)); } +#ifndef HAVE_ARC4RANDOM /* random value initilization */ srandom((u_long)time(NULL)); +#endif /* warn if accept_rtadv is down */ if (!getinet6sysctl(IPV6CTL_ACCEPT_RTADV)) @@ -172,19 +179,23 @@ main(argc, argv) if (signal(SIGUSR1, (void *)rtsold_set_dump_file) < 0) errx(1, "failed to set signal for dump status"); + /* + * Open a socket for sending RS and receiving RA. + * This should be done before calling ifinit(), since the function + * uses the socket. + */ + if ((s = sockopen()) < 0) + errx(1, "failed to open a socket"); + /* configuration per interface */ if (ifinit()) errx(1, "failed to initilizatoin interfaces"); while (argc--) { if (ifconfig(*argv)) - errx(1, "failed to initilize %s", *argv); + errx(1, "failed to initialize %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"); @@ -210,7 +221,6 @@ main(argc, argv) FD_ZERO(&fdset); FD_SET(s, &fdset); while (1) { /* main loop */ - extern int errno; int e; struct fd_set select_fd = fdset; @@ -218,7 +228,7 @@ main(argc, argv) do_dump = 0; rtsold_dump_file(dumpfilename); } - + timeout = rtsol_check_timer(); if (once) { @@ -269,11 +279,13 @@ ifconfig(char *ifname) if (find_ifinfo(sdl->sdl_index)) { warnmsg(LOG_ERR, __FUNCTION__, "interface %s was already cofigured", ifname); + free(sdl); return(-1); } if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) { warnmsg(LOG_ERR, __FUNCTION__, "memory allocation failed"); + free(sdl); return(-1); } memset(ifinfo, 0, sizeof(*ifinfo)); @@ -318,11 +330,38 @@ ifconfig(char *ifname) return(0); bad: - free(ifinfo); free(ifinfo->sdl); + free(ifinfo); return(-1); } +#if 0 +static int +ifreconfig(char *ifname) +{ + struct ifinfo *ifi, *prev; + int rv; + + prev = NULL; + for (ifi = iflist; ifi; ifi = ifi->next) { + if (strncmp(ifi->ifname, ifname, sizeof(ifi->ifname)) == 0) + break; + prev = ifi; + } + prev->next = ifi->next; + + rv = ifconfig(ifname); + + /* reclaim it after ifconfig() in case ifname is pointer inside ifi */ + if (ifi->rs_data) + free(ifi->rs_data); + free(ifi->sdl); + free(ifi); + + return rv; +} +#endif + struct ifinfo * find_ifinfo(int ifindex) { @@ -480,8 +519,8 @@ rtsol_check_timer() void rtsol_timer_update(struct ifinfo *ifinfo) { -#define MILLION 1000000 -#define DADRETRY 10 /* XXX: adhoc */ +#define MILLION 1000000 +#define DADRETRY 10 /* XXX: adhoc */ long interval; struct timeval now; @@ -499,14 +538,18 @@ rtsol_timer_update(struct ifinfo *ifinfo) break; case IFS_IDLE: if (mobile_node) { - /* XXX should be configurable */ + /* XXX should be configurable */ ifinfo->timer.tv_sec = 3; } else ifinfo->timer = tm_max; /* stop timer(valid?) */ break; case IFS_DELAY: +#ifndef HAVE_ARC4RANDOM interval = random() % (MAX_RTR_SOLICITATION_DELAY * MILLION); +#else + interval = arc4random() % (MAX_RTR_SOLICITATION_DELAY * MILLION); +#endif ifinfo->timer.tv_sec = interval / MILLION; ifinfo->timer.tv_usec = interval % MILLION; break; @@ -541,7 +584,7 @@ rtsol_timer_update(struct ifinfo *ifinfo) } /* timer related utility functions */ -#define MILLION 1000000 +#define MILLION 1000000 /* result = a + b */ static void diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h index afb5088967be8..f5c722bfbafec 100644 --- a/usr.sbin/rtsold/rtsold.h +++ b/usr.sbin/rtsold/rtsold.h @@ -1,7 +1,7 @@ /* * 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: @@ -13,7 +13,7 @@ * 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 @@ -33,7 +33,7 @@ struct ifinfo { struct ifinfo *next; /* pointer to the next interface */ struct sockaddr_dl *sdl; /* link-layer address */ - char ifname[16]; /* interface name */ + char ifname[IF_NAMESIZE]; /* interface name */ int active; /* interface status */ int probeinterval; /* interval of probe timer(if necessary) */ int probetimer; /* rest of probe timer */ @@ -43,6 +43,7 @@ struct ifinfo { int dadcount; struct timeval timer; struct timeval expire; + int errors; /* # of errors we've got - detect wedge */ int racnt; /* total # of valid RAs it have got */ @@ -51,11 +52,11 @@ struct ifinfo { }; /* per interface status */ -#define IFS_IDLE 0 -#define IFS_DELAY 1 -#define IFS_PROBE 2 -#define IFS_DOWN 3 -#define IFS_TENTATIVE 4 +#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; diff --git a/usr.sbin/setkey/Makefile b/usr.sbin/setkey/Makefile index e6fbadcdf2aa6..8feb0a66e6b5a 100644 --- a/usr.sbin/setkey/Makefile +++ b/usr.sbin/setkey/Makefile @@ -29,11 +29,18 @@ PROG= setkey SRCS= setkey.c parse.y token.l CFLAGS+=-g +CFLAGS+=-I${.CURDIR}/../../lib/libipsec DPADD= ${LIBL} ${LIBY} LDADD= -ll -ly CLEANFILES+= y.tab.c y.tab.h key_test.o keytest YFLAGS+=-d +# libpfkey. +# ipsec_strerror.c is for avoiding shlib reference to non-exported function. +.PATH: ${.CURDIR}/../../lib/libipsec ${.CURDIR}/../../sys/netkey +SRCS+= pfkey.c pfkey_dump.c key_debug.c ipsec_strerror.c +CFLAGS+=-I${.CURDIR}/../../lib/libipsec -I${.CURDIR}/../../sys/netkey + SCRIPTS= scriptdump BINOWN = root diff --git a/usr.sbin/setkey/parse.y b/usr.sbin/setkey/parse.y index 761c34d6e6d8c..0eea4c1faaf2a 100644 --- a/usr.sbin/setkey/parse.y +++ b/usr.sbin/setkey/parse.y @@ -1,7 +1,10 @@ +/* $FreeBSD$ */ +/* $KAME: parse.y,v 1.29 2000/06/10 14:17:44 sakane Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 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: @@ -13,7 +16,7 @@ * 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 @@ -25,10 +28,7 @@ * 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$ */ -/* KAME $Id: parse.y,v 1.7 1999/10/27 17:08:57 sakane Exp $ */ %{ #include <sys/types.h> @@ -45,48 +45,52 @@ #include <string.h> #include <unistd.h> #include <stdio.h> +#include <netdb.h> #include <ctype.h> #include <errno.h> -#include <netdb.h> +#include "libpfkey.h" #include "vchar.h" #define ATOX(c) \ (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) -u_int p_type; -u_int32_t p_spi; -struct sockaddr *p_src, *p_dst; -u_int p_prefs, p_prefd, p_upper; -u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; -u_int p_key_enc_len, p_key_auth_len; -caddr_t p_key_enc, p_key_auth; -time_t p_lt_hard, p_lt_soft; +u_int p_type; +u_int32_t p_spi; +struct sockaddr *p_src, *p_dst; +u_int p_prefs, p_prefd, p_upper; +u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; +u_int32_t p_reqid; +u_int p_key_enc_len, p_key_auth_len; +caddr_t p_key_enc, p_key_auth; +time_t p_lt_hard, p_lt_soft; -u_int p_policy_len; -char *p_policy; +u_int p_policy_len; +char *p_policy; /* temporary buffer */ -static struct sockaddr *pp_addr; -static u_int pp_prefix; -static u_int pp_port; -static caddr_t pp_key; +static struct sockaddr *pp_addr; +static u_int pp_prefix; +static u_int pp_port; +static caddr_t pp_key; -extern u_char m_buf[BUFSIZ]; -extern int m_len; -extern char cmdarg[8192]; -extern int f_debug; +extern u_char m_buf[BUFSIZ]; +extern int m_len; +extern char cmdarg[8192]; +extern int f_debug; -int setkeymsg __P((void)); -static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); -void parse_init __P((void)); -void free_buffer __P((void)); +int setkeymsg __P((void)); +static struct addrinfo *parse_addr __P((char *, char *, int)); +static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); +void parse_init __P((void)); +void free_buffer __P((void)); -extern int setkeymsg __P((void)); -extern int sendkeymsg __P((void)); +extern int setkeymsg __P((void)); +extern int sendkeymsg __P((void)); -extern int yylex __P((void)); -extern void yyerror __P((char *)); +extern int yylex __P((void)); +extern void yyfatal __P((const char *)); +extern void yyerror __P((const char *)); %} %union { @@ -96,11 +100,11 @@ extern void yyerror __P((char *)); %token EOT %token ADD GET DELETE FLUSH DUMP -%token IP4_ADDRESS IP6_ADDRESS PREFIX PORT PORTANY +%token ADDRESS PREFIX PORT PORTANY %token UP_PROTO PR_ESP PR_AH PR_IPCOMP %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI -%token F_MODE MODE -%token F_EXT EXTENSION +%token F_MODE MODE F_REQID +%token F_EXT EXTENSION NOCYCLICSEQ %token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP %token F_LIFETIME_HARD F_LIFETIME_SOFT %token DECSTRING QUOTEDSTRING HEXSTRING ANY @@ -108,6 +112,14 @@ extern void yyerror __P((char *)); %token SPDADD SPDDELETE SPDDUMP SPDFLUSH %token F_POLICY PL_REQUESTS +%type <num> PORT PREFIX EXTENSION MODE +%type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP +%type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP +%type <num> DECSTRING +%type <val> ADDRESS PL_REQUESTS +%type <val> key_string policy_requests +%type <val> QUOTEDSTRING HEXSTRING + %% commands : /*NOTHING*/ @@ -146,13 +158,23 @@ add_command /* delete */ delete_command : DELETE { p_type = SADB_DELETE; } - sa_selector_spec extension_spec EOT + sa_selector_spec extension_spec + { + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsoleted."); + } + EOT ; /* get command */ get_command : GET { p_type = SADB_GET; } - sa_selector_spec extension_spec EOT + sa_selector_spec extension_spec + { + if (p_mode != IPSEC_MODE_ANY) + yyerror("WARNING: mode is obsoleted."); + } + EOT ; /* flush */ @@ -179,7 +201,7 @@ protocol_spec | PR_ESP { p_satype = SADB_SATYPE_ESP; - if ($1.num == 1) + if ($1 == 1) p_ext |= SADB_X_EXT_OLD; else p_ext &= ~SADB_X_EXT_OLD; @@ -187,7 +209,7 @@ protocol_spec | PR_AH { p_satype = SADB_SATYPE_AH; - if ($1.num == 1) + if ($1 == 1) p_ext |= SADB_X_EXT_OLD; else p_ext &= ~SADB_X_EXT_OLD; @@ -199,18 +221,18 @@ protocol_spec ; spi - : DECSTRING { p_spi = $1.num; } + : DECSTRING { p_spi = $1; } | HEXSTRING { caddr_t bp; - caddr_t yp = $1.val.buf; + caddr_t yp = $1.buf; char buf0[4], buf[4]; int i, j; /* sanity check */ - if ($1.val.len > 4) { + if ($1.len > 4) { yyerror("SPI too big."); - free($1.val.buf); + free($1.buf); return -1; } @@ -223,13 +245,13 @@ spi /* initialize */ for (i = 0; i < 4; i++) buf[i] = 0; - for (j = $1.val.len - 1, i = 3; j >= 0; j--, i--) + for (j = $1.len - 1, i = 3; j >= 0; j--, i--) buf[i] = buf0[j]; /* XXX: endian */ p_spi = ntohl(*(u_int32_t *)buf); - free($1.val.buf); + free($1.buf); } ; @@ -249,16 +271,16 @@ ah_spec ; ipcomp_spec - : F_COMP ALG_COMP { p_alg_enc = $2.num; } - | F_COMP ALG_COMP { p_alg_enc = $2.num; } + : F_COMP ALG_COMP { p_alg_enc = $2; } + | F_COMP ALG_COMP { p_alg_enc = $2; } F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; } ; enc_alg - : ALG_ENC { p_alg_enc = $1.num; } + : ALG_ENC { p_alg_enc = $1; } | ALG_ENC_DESDERIV { - p_alg_enc = $1.num; + p_alg_enc = $1; if (p_ext & SADB_X_EXT_OLD) { yyerror("algorithm mismatched."); return -1; @@ -267,7 +289,7 @@ enc_alg } | ALG_ENC_DES32IV { - p_alg_enc = $1.num; + p_alg_enc = $1; if (!(p_ext & SADB_X_EXT_OLD)) { yyerror("algorithm mismatched."); return -1; @@ -286,7 +308,7 @@ enc_key } | key_string { - p_key_enc_len = $1.val.len; + p_key_enc_len = $1.len; p_key_enc = pp_key; if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, @@ -299,7 +321,7 @@ enc_key ; auth_alg - : ALG_AUTH { p_alg_auth = $1.num; } + : ALG_AUTH { p_alg_auth = $1; } ; auth_key @@ -312,7 +334,7 @@ auth_key } | key_string { - p_key_auth_len = $1.val.len; + p_key_auth_len = $1.len; p_key_auth = pp_key; if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, @@ -327,20 +349,20 @@ auth_key key_string : QUOTEDSTRING { - pp_key = $1.val.buf; + pp_key = $1.buf; /* free pp_key later */ } | HEXSTRING { caddr_t bp; - caddr_t yp = $1.val.buf; + caddr_t yp = $1.buf; - if ((pp_key = malloc($1.val.len)) == 0) { - free($1.val.buf); - yyerror(strerror(errno)); + if ((pp_key = malloc($1.len)) == 0) { + free($1.buf); + yyerror("not enough core"); return -1; } - memset(pp_key, 0, $1.val.len); + memset(pp_key, 0, $1.len); bp = pp_key; while (*yp) { @@ -348,7 +370,7 @@ key_string yp += 2, bp++; } - free($1.val.buf); + free($1.buf); } ; @@ -358,9 +380,11 @@ extension_spec ; extension - : F_EXT EXTENSION { p_ext |= $1.num; } - | F_MODE MODE { p_mode = $2.num; } + : F_EXT EXTENSION { p_ext |= $2; } + | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } + | F_MODE MODE { p_mode = $2; } | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } + | F_REQID DECSTRING { p_reqid = $2; } | F_REPLAY DECSTRING { if (p_ext & SADB_X_EXT_OLD) { @@ -368,10 +392,10 @@ extension "only use on new spec."); return -1; } - p_replay = $2.num; + p_replay = $2; } - | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2.num; } - | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2.num; } + | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } + | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } ; /* definition about command for SPD management */ @@ -391,7 +415,7 @@ spddelete_command: p_type = SADB_X_SPDDELETE; p_satype = SADB_SATYPE_UNSPEC; } - sp_selector_spec EOT + sp_selector_spec policy_spec EOT ; spddump_command: @@ -416,97 +440,107 @@ spdflush_command: sp_selector_spec : ipaddress { p_src = pp_addr; } prefix { p_prefs = pp_prefix; } - port { _INPORTBYSA(p_src) = htons(pp_port); } + port + { + switch (p_src->sa_family) { + case AF_INET: + ((struct sockaddr_in *)p_src)->sin_port = + htons(pp_port); + break; +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)p_src)->sin6_port = + htons(pp_port); + break; +#endif + default: + exit(1); /*XXX*/ + } + } ipaddress { p_dst = pp_addr; } prefix { p_prefd = pp_prefix; } - port { _INPORTBYSA(p_dst) = htons(pp_port); } + port + { + switch (p_dst->sa_family) { + case AF_INET: + ((struct sockaddr_in *)p_dst)->sin_port = + htons(pp_port); + break; +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)p_dst)->sin6_port = + htons(pp_port); + break; +#endif + default: + exit(1); /*XXX*/ + } + } upper_spec - ; - -ipaddress - : IP4_ADDRESS { - struct sockaddr_in *in; - u_int sa_len = $1.val.len; - - if ((in = (struct sockaddr_in *)malloc(sa_len)) == 0) { - yyerror(strerror(errno)); - free($1.val.buf); - return -1; + /* XXX is it something userland should check? */ +#if 0 + switch (p_upper) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY + || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) { + yyerror("port number must be \"any\"."); + return -1; + } + if ((pp_addr->sa_family == AF_INET6 + && p_upper == IPPROTO_ICMP) + || (pp_addr->sa_family == AF_INET + && p_upper == IPPROTO_ICMPV6)) { + yyerror("upper layer protocol " + "mismatched.\n"); + return -1; + } + break; + default: + break; } - memset((caddr_t)in, 0, sa_len); - - in->sin_family = PF_INET; - in->sin_len = sa_len; - in->sin_port = IPSEC_PORT_ANY; - (void)inet_pton(PF_INET, $1.val.buf, &in->sin_addr); - - pp_addr = (struct sockaddr *)in; - free($1.val.buf); +#endif } - | IP6_ADDRESS + ; + +ipaddress + : ADDRESS { -#ifdef INET6 - struct sockaddr_in6 *in6; - u_int sa_len = $1.val.len; - struct addrinfo hints, *res; - int ret_gai; + struct addrinfo *res; - if ((in6 = (struct sockaddr_in6 *)malloc(sa_len)) == 0) { - free($1.val.buf); - yyerror(strerror(errno)); + res = parse_addr($1.buf, NULL, AI_NUMERICHOST); + if (res == NULL) { + free($1.buf); return -1; } - memset((caddr_t)in6, 0, sa_len); - - bzero(&hints, sizeof(struct addrinfo)); - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = AF_INET6; - ret_gai = getaddrinfo($1.val.buf, NULL, &hints, &res); - if (ret_gai) { - free($1.val.buf); - free(in6); - yyerror(gai_strerror(ret_gai)); - if (ret_gai == EAI_SYSTEM) - yyerror(strerror(errno)); - return -1; + pp_addr = (struct sockaddr *)malloc(res->ai_addrlen); + if (!pp_addr) { + yyerror("not enough core"); + goto end; } - (void)memcpy(in6, res->ai_addr, res->ai_addrlen); - - /* - * XXX: If the scope of the destination is link-local, - * embed the scope-id(in this case, interface index) - * into the address. - */ - if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr) && - in6->sin6_scope_id != 0) - *(u_short *)&in6->sin6_addr.s6_addr[2] = - htons(in6->sin6_scope_id & 0xffff); + memcpy(pp_addr, res->ai_addr, res->ai_addrlen); + end: freeaddrinfo(res); - - pp_addr = (struct sockaddr *)in6; -#else - yyerror("IPv6 address not supported"); -#endif - free($1.val.buf); + free($1.buf); } ; prefix : /*NOTHING*/ { pp_prefix = ~0; } - | PREFIX { pp_prefix = $1.num; } + | PREFIX { pp_prefix = $1; } ; port : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; } - | PORT { pp_port = $1.num; } + | PORT { pp_port = $1; } | PORTANY { pp_port = IPSEC_PORT_ANY; } ; upper_spec - : DECSTRING { p_upper = $1.num; } - | UP_PROTO { p_upper = $1.num; } + : DECSTRING { p_upper = $1; } + | UP_PROTO { p_upper = $1; } | PR_ESP { p_upper = IPPROTO_ESP; }; | PR_AH { p_upper = IPPROTO_AH; }; | PR_IPCOMP { p_upper = IPPROTO_IPCOMP; }; @@ -516,9 +550,9 @@ upper_spec policy_spec : F_POLICY policy_requests { - p_policy = ipsec_set_policy($2.val.buf, $2.val.len); + p_policy = ipsec_set_policy($2.buf, $2.len); if (p_policy == NULL) { - free($2.val.buf); + free($2.buf); p_policy = NULL; yyerror(ipsec_strerror()); return -1; @@ -526,13 +560,12 @@ policy_spec p_policy_len = ipsec_get_policylen(p_policy); - free($2.val.buf); + free($2.buf); } ; -policy_requests: - /*NOTHING*/ - | PL_REQUESTS { $$ = $1; } +policy_requests + : PL_REQUESTS { $$ = $1; } ; %% @@ -546,7 +579,6 @@ setkeymsg() m_msg.sadb_msg_type = p_type; m_msg.sadb_msg_errno = 0; m_msg.sadb_msg_satype = p_satype; - m_msg.sadb_msg_mode = p_mode; m_msg.sadb_msg_reserved = 0; m_msg.sadb_msg_seq = 0; m_msg.sadb_msg_pid = getpid(); @@ -629,6 +661,7 @@ setkeymsg() case SADB_GET: { struct sadb_sa m_sa; + struct sadb_x_sa2 m_sa2; struct sadb_address m_addr; u_int len; @@ -645,14 +678,36 @@ setkeymsg() memcpy(m_buf + m_len, &m_sa, len); m_len += len; + len = sizeof(struct sadb_x_sa2); + m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); + m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; + m_sa2.sadb_x_sa2_mode = p_mode; + m_sa2.sadb_x_sa2_reqid = p_reqid; + + memcpy(m_buf + m_len, &m_sa2, len); + m_len += len; + /* set src */ m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + PFKEY_ALIGN8(p_src->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; - m_addr.sadb_address_prefixlen = - _INALENBYAF(p_src->sa_family) << 3; + switch (p_src->sa_family) { + case AF_INET: + m_addr.sadb_address_prefixlen = + sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + m_addr.sadb_address_prefixlen = + sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, @@ -665,8 +720,21 @@ setkeymsg() + PFKEY_ALIGN8(p_dst->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; - m_addr.sadb_address_prefixlen = - _INALENBYAF(p_dst->sa_family) << 3; + switch (p_dst->sa_family) { + case AF_INET: + m_addr.sadb_address_prefixlen = + sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + m_addr.sadb_address_prefixlen = + sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, @@ -681,17 +749,15 @@ setkeymsg() break; case SADB_X_SPDADD: + case SADB_X_SPDDELETE: { + struct sadb_address m_addr; + u_int8_t plen; + memcpy(m_buf + m_len, p_policy, p_policy_len); m_len += p_policy_len; free(p_policy); p_policy = NULL; - } - /* FALLTHROUGH */ - - case SADB_X_SPDDELETE: - { - struct sadb_address m_addr; /* set src */ m_addr.sadb_address_len = @@ -699,9 +765,21 @@ setkeymsg() + PFKEY_ALIGN8(p_src->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; m_addr.sadb_address_proto = p_upper; + switch (p_src->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_prefixlen = - (p_prefs != ~0 ? p_prefs : - _INALENBYAF(p_src->sa_family) << 3); + (p_prefs != ~0 ? p_prefs : plen); m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, @@ -714,9 +792,21 @@ setkeymsg() + PFKEY_ALIGN8(p_dst->sa_len)); m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; m_addr.sadb_address_proto = p_upper; + switch (p_dst->sa_family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; +#ifdef INET6 + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; +#endif + default: + yyerror("unsupported address family"); + exit(1); /*XXX*/ + } m_addr.sadb_address_prefixlen = - (p_prefd != ~0 ? p_prefd : - _INALENBYAF(p_dst->sa_family) << 3); + (p_prefd != ~0 ? p_prefd : plen); m_addr.sadb_address_reserved = 0; setvarbuf(&m_len, @@ -731,6 +821,30 @@ setkeymsg() return 0; } +static struct addrinfo * +parse_addr(host, port, flag) + char *host; + char *port; + int flag; +{ + struct addrinfo hints, *res = NULL; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = flag; + error = getaddrinfo(host, port, &hints, &res); + if (error != 0) { + yyerror(gai_strerror(error)); + return NULL; + } + if (res->ai_next != NULL) { + yyerror(gai_strerror(error)); + } + return res; +} + static int setvarbuf(off, ebuf, elen, vbuf, vlen) caddr_t vbuf; @@ -757,11 +871,12 @@ parse_init() p_upper = 0; p_satype = 0; - p_ext = SADB_X_EXT_NONE; + p_ext = SADB_X_EXT_CYCSEQ; p_alg_enc = SADB_EALG_NONE; p_alg_auth = SADB_AALG_NONE; p_mode = IPSEC_MODE_ANY; - p_replay = 4; + p_reqid = 0; + p_replay = 0; p_key_enc_len = p_key_auth_len = 0; p_key_enc = p_key_auth = 0; p_lt_hard = p_lt_soft = 0; diff --git a/usr.sbin/setkey/sample.cf b/usr.sbin/setkey/sample.cf index 886c449a35f19..978289d34a139 100644 --- a/usr.sbin/setkey/sample.cf +++ b/usr.sbin/setkey/sample.cf @@ -170,7 +170,7 @@ add fec0:0:0:2::1 fec0:0:0:1::1 esp 0x10004 get fec0:0:0:1::1 fec0:0:0:2::2 ah 0x10004 ; # Also delete command, you can delete a entry of either SP or SA. -spddelete out fec0:0:0:1::/64 fec0:0:0:2:/64 any ; +spddelete fec0:0:0:1::/64 fec0:0:0:2::/64 any -P out; delete fec0:0:0:1::1 fec0:0:0:2::2 ah 0x10004 ; # By dump command, you can dump all entry of either SP or SA. @@ -204,7 +204,7 @@ add ::1 ::1 esp 10013 -m tunnel -E rc5-cbc "testtest1234" ; add ::1 ::1 esp 10014 -m any -E rc5-cbc "testtest1234" ; add ::1 ::1 esp 10015 -m transport -f zero-pad -E simple ; add ::1 ::1 esp 10016 -m tunnel -f random-pad -r 8 -lh 100 -ls 80 -E simple ; -add ::1 ::1 esp 10017 -m transport -f seq-pad -f cyclic-seq -E simple ; +add ::1 ::1 esp 10017 -m transport -f seq-pad -f nocyclic-seq -E simple ; add ::1 ::1 esp 10018 -m transport -E simple ; #add ::1 ::1 ah 20000 -m transport -A null ; add ::1 ::1 ah 20001 -m any -A hmac-md5 "1234123412341234"; diff --git a/usr.sbin/setkey/scriptdump.pl b/usr.sbin/setkey/scriptdump.pl index 5df9b4f4fd7b2..aa365449517f0 100644 --- a/usr.sbin/setkey/scriptdump.pl +++ b/usr.sbin/setkey/scriptdump.pl @@ -20,8 +20,8 @@ open(IN, "setkey -D |") || die; foreach $_ (<IN>) { if (/^[^\t]/) { ($src, $dst) = split(/\s+/, $_); - } elsif (/^\t(esp|ah) mode=(\S+) spi=(\d+).*replay=(\d+)/) { - ($proto, $ipsecmode, $spi, $replay) = ($1, $2, $3, $4); + } elsif (/^\t(esp|ah) mode=(\S+) spi=(\d+).*reqid=(\d+)/) { + ($proto, $ipsecmode, $spi, $reqid) = ($1, $2, $3, $4); } elsif (/^\tE: (\S+) (.*)/) { $ealgo = $1; $ekey = $2; @@ -32,17 +32,19 @@ foreach $_ (<IN>) { $akey = $2; $akey =~ s/\s//g; $akey =~ s/^/0x/g; - } elsif (/^\tstate=/) { + } elsif (/^\treplay=(\d+) flags=(0x\d+) state=/) { print "$mode $src $dst $proto $spi -m $ipsecmode"; - print " -r $replay" if $replay; + $replay = $1; + print " -u $reqid" if $reqid; if ($mode eq 'add') { + print " -r $replay" if $replay; if ($proto eq 'esp') { print " -E $ealgo $ekey" if $ealgo; print " -A $aalgo $akey" if $aalgo; } elsif ($proto eq 'ah') { print " -A $aalgo $akey" if $aalgo; } - } + } print ";\n"; $src = $dst = $upper = $proxy = ''; diff --git a/usr.sbin/setkey/setkey.8 b/usr.sbin/setkey/setkey.8 index ffe1297872e0a..4736657c8356d 100644 --- a/usr.sbin/setkey/setkey.8 +++ b/usr.sbin/setkey/setkey.8 @@ -1,6 +1,9 @@ +.\" $FreeBSD$ +.\" $KAME: setkey.8,v 1.28 2000/06/16 12:03:46 sakane Exp $ +.\" .\" Copyright (C) 1995, 1996, 1997, 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: @@ -12,7 +15,7 @@ .\" 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 @@ -25,15 +28,14 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: setkey.8,v 1.14 1999/10/27 17:08:58 sakane Exp $ -.\" $FreeBSD$ -.\" .Dd May 17, 1998 .Dt SETKEY 8 -.Os +.Os KAME +.\" .Sh NAME .Nm setkey -.Nd manually manipulate the SA/SP database. +.Nd manually manipulate the IPsec SA/SP database. +.\" .Sh SYNOPSIS .Nm setkey .Op Fl dv @@ -50,19 +52,20 @@ .Nm setkey .Op Fl h .Fl x -.\" +.\" .Sh DESCRIPTION .Nm -updates, or lists the content of, Security Association Database (SAD) entries -in the kernel as well as Security Policy Database (SPD) entries. +addes, updates, dumpes, or flushes +Security Association Database (SAD) entries +as well as Security Policy Database (SPD) entries in the kernel. .Pp .Nm -takes a series of operation from standard input +takes a series of operations from the standard input .Po if invoked with .Fl c .Pc -or file named +or the file named .Ar filename .Po if invoked with @@ -75,21 +78,23 @@ If with .Fl P , the SPD entries are dumped. .It Fl F -Flush the SAD. +Flush the SAD entries. If with .Fl P , -the SPD are flushed. +the SPD entries are flushed. .It Fl a .Nm -usually do not display dead SAD entries on +usually does not display dead SAD entries with .Fl D . -With +If with .Fl a , -dead SAD entries will be displayed as well. -Dead SAD entries are kept in the kernel, -when they are referenced from any of SPD entries in the kernel. +the dead SAD entries will be displayed as well. +A dead SAD entry means that +it has been expired but remains +because it is referenced by SPD entries. .It Fl d -Enable debugging messages. +Enable to print debugging messages for command parser, +without talking to kernel. It is not used usually. .It Fl x Loop forever and dump all the messages transmitted to .Dv PF_KEY @@ -98,7 +103,6 @@ socket. Add hexadecimal dump on .Fl x mode. -The order is significant. .It Fl l Loop forever with short output on .Fl D . @@ -111,10 +115,8 @@ including messages sent from other processes .Pc . .El .Pp -Operation has the following grammar. -Note that lines, that start with a -hashmark ('#') are treated as comment lines. -Description of meta-arguments follows. +Operations have the following grammar. Note that lines starting with +hashmarks ('#') are treated as comment lines. .Bl -tag -width Ds .It Xo .Li add @@ -123,51 +125,49 @@ Description of meta-arguments follows. .Ar algorithm... .Li ; .Xc -Add a SAD entry. +Add an SAD entry. .\" .It Xo .Li get .Ar src Ar dst Ar protocol Ar spi -.Op Ar mode .Li ; .Xc -Show a SAD entry. +Show an SAD entry. .\" .It Xo .Li delete .Ar src Ar dst Ar protocol Ar spi -.Op Ar mode .Li ; .Xc -Remove a SAD entry. +Remove an SAD entry. .\" .It Xo .Li flush .Op Ar protocol .Li ; .Xc -Clear all SAD entries that matches the options. +Clear all SAD entries matched by the options. .\" .It Xo .Li dump .Op Ar protocol .Li ; .Xc -Dumps all SAD entries that matches the options. +Dumps all SAD entries matched by the options. .\" .It Xo .Li spdadd .Ar src_range Ar dst_range Ar upperspec Ar policy .Li ; .Xc -Add a SPD entry. +Add an SPD entry. .\" .It Xo .Li spddelete -.Ar src_range Ar dst_range Ar upperspec +.Ar src_range Ar dst_range Ar upperspec Fl P Ar direction .Li ; .Xc -Delete a SPD entry. +Delete an SPD entry. .\" .It Xo .Li spdflush @@ -215,8 +215,9 @@ IPCOMP .\" .Pp .It Ar spi -Security Parameter Index (SPI) for the SA and SPD. +Security Parameter Index (SPI) for the SAD and the SPD. It must be decimal number or hexadecimal number +You can not use the set of SPI values in the range 0 through 255. .Po with .Li 0x @@ -225,30 +226,40 @@ attached .\" .Pp .It Ar extensions -takes some of the following: -.Bl -tag -width Fl -compact +take some of the following: +.Bl -tag -width Fl -compact +.\" .It Fl m Ar mode -Specify an security protocol mode for use. By default, -.Li any . +Specify a security protocol mode for use. .Ar mode is one of following: .Li transport , tunnel or .Li any . +The default value is +.Li any . +.\" .It Fl r Ar size Specify window size of bytes for replay prevention. .Ar size must be decimal number in 32-bit word. If .Ar size is zero or not specified, replay check don't take place. +.\" +.It Fl u Ar id +Specify the identifier of policy. See also +.Xr ipsec_set_policy 3 . +.\" .It Fl f Ar pad_option .Ar pad_option is one of following: .Li zero-pad , random-pad or .Li seq-pad -.It Fl f Li cyclic-seq -Allow cyclic sequence number. +.\" +.It Fl f Li nocyclic-seq +Don't allow cyclic sequence number. +.\" .It Fl lh Ar time .It Fl ls Ar time Specify hard/soft lifetime. @@ -256,7 +267,7 @@ Specify hard/soft lifetime. .\" .Pp .It Ar algorithm -.Bl -tag -width Fl -compact +.Bl -tag -width Fl -compact .It Fl E Ar ealgo Ar key Specify encryption algorithm. .It Fl A Ar aalgo Ar key @@ -268,7 +279,7 @@ is used for esp, it will be treated as ESP payload authentication algorithm. Specify compression algorithm. If .Fl R -is specified with +is not specified with .Li ipcomp line, the kernel will use well-known IPComp CPI .Pq compression parameter index @@ -280,7 +291,7 @@ field is only for kernel internal use in this case. .\"Therefore, compression protocol number will appear on IPComp CPI field. If .Fl R -is not used, +is used, the value on .Ar spi field will appear on IPComp CPI field on outgoing packets. @@ -311,7 +322,7 @@ SAs accept only. .Pp .Ar key -must be double-quoted character string or a series of hexadecimal digits. +must be double-quoted character string or series of hexadecimal digits. .Pp Possible values for .Ar ealgo , @@ -322,7 +333,7 @@ are specified in separate section. .\" .It Ar src_range .It Ar dst_range -These are selection of the secure communication is specified as +These are selections of the secure communication specified as IPv4/v6 address or IPv4/v6 address range, and it may accompany TCP/UDP port specification. This takes the following form: @@ -365,7 +376,7 @@ NOTE: .Ar upperspec does not work against forwarding case at this moment, as it requires extra reassembly at forwarding node -.Pq not implemented as this moment . +.Pq not implemented at this moment . .\" .It Ar policy .Ar policy @@ -427,15 +438,15 @@ is to be one of the following: or .Li require . .Li default -means kernel consults to the system wide default against protocol you +means the kernel consults to the system wide default against protocol you specified, e.g. .Li esp_trans_deflev -sysctl variable, when kernel processes the packet. +sysctl variable, when the kernel processes the packet. .Li use -means that kernel use a SA if it's available, -otherwise kernel keeps normal operation. +means that the kernel use a SA if it's available, +otherwise the kernel keeps normal operation. .Li require -means SA is required whenever kernel deals with the packet. +means SA is required whenever the kernel deals with the packet. Note that .Dq Li discard and @@ -456,7 +467,7 @@ The following list shows the supported algorithms. and .Sy algorithm are almost orthogonal. -Following are the list of authentication algorithms that can be used as +Followings are the list of authentication algorithms that can be used as .Ar aalgo in .Fl A Ar aalgo @@ -477,7 +488,7 @@ keyed-sha1 160 ah: 96bit ICV (no document) null 0 to 2048 for debugging .Ed .Pp -Following are the list of encryption algorithms that can be used as +Followings are the list of encryption algorithms that can be used as .Ar ealgo in .Fl E Ar ealgo @@ -497,7 +508,7 @@ des-deriv 64 ipsec-ciph-des-derived-01 (expired) 3des-deriv 192 no document .Ed .Pp -Following are the list of compression algorithms that can be used as +Followings are the list of compression algorithms that can be used as .Ar calgo in .Fl C Ar calgo @@ -510,7 +521,7 @@ algorithm comment deflate rfc2394 lzs rfc2395 .Ed -.\" +.\" .Sh EXAMPLES .Bd -literal -offset add 3ffe:501:4819::1 3ffe:501:481d::1 esp 123457 @@ -533,20 +544,18 @@ spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any -P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ; .Ed -.\" +.\" .Sh RETURN VALUES The command exits with 0 on success, and non-zero on errors. -.\" +.\" .Sh SEE ALSO .Xr ipsec_set_policy 3 , .Xr sysctl 8 -.\" +.\" .Sh HISTORY The .Nm command first appeared in WIDE Hydrangea IPv6 protocol stack kit. The command was completely re-designed in June 1998. -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 +.\" +.\" .Sh BUGS diff --git a/usr.sbin/setkey/setkey.c b/usr.sbin/setkey/setkey.c index 73edc3f2bbc27..b1e1c1e3094ba 100644 --- a/usr.sbin/setkey/setkey.c +++ b/usr.sbin/setkey/setkey.c @@ -1,7 +1,10 @@ +/* $FreeBSD$ */ +/* $KAME: setkey.c,v 1.14 2000/06/10 06:47:09 sakane Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 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: @@ -13,7 +16,7 @@ * 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 @@ -25,10 +28,7 @@ * 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$ */ -/* KAME $Id: setkey.c,v 1.5 1999/10/26 09:39:37 sakane Exp $ */ #include <sys/types.h> #include <sys/param.h> @@ -51,40 +51,42 @@ #include <errno.h> #include <netdb.h> -void Usage __P((void)); -int main __P((int, char **)); -int get_supported __P((void)); -void sendkeyshort __P((u_int)); -void promisc __P((void)); -int sendkeymsg __P((void)); -int postproc __P((struct sadb_msg *, int)); -const char *numstr __P((int)); -void shortdump_hdr __P((void)); -void shortdump __P((struct sadb_msg *)); +#include "libpfkey.h" + +void Usage __P((void)); +int main __P((int, char **)); +int get_supported __P((void)); +void sendkeyshort __P((u_int)); +void promisc __P((void)); +int sendkeymsg __P((void)); +int postproc __P((struct sadb_msg *, int)); +const char *numstr __P((int)); +void shortdump_hdr __P((void)); +void shortdump __P((struct sadb_msg *)); #define MODE_SCRIPT 1 #define MODE_CMDDUMP 2 #define MODE_CMDFLUSH 3 +#define MODE_PROMISC 4 int so; -int f_forever = 0; -int f_all = 0; -int f_debug = 0; -int f_verbose = 0; -int f_mode = 0; -int f_cmddump = 0; -int f_policy = 0; -int f_promisc = 0; -int f_hexdump = 0; -char *pname; +int f_forever = 0; +int f_all = 0; +int f_debug = 0; +int f_verbose = 0; +int f_mode = 0; +int f_cmddump = 0; +int f_policy = 0; +int f_hexdump = 0; +char *pname; -u_char m_buf[BUFSIZ]; -u_int m_len; +u_char m_buf[BUFSIZ]; +u_int m_len; -extern int lineno; +extern int lineno; -extern int parse __P((FILE **)); +extern int parse __P((FILE **)); void Usage() @@ -95,7 +97,7 @@ Usage() printf("\t%s [-Pdv] -F\n", pname); printf("\t%s [-h] -x\n", pname); pfkey_close(so); - exit(0); + exit(1); } int @@ -139,9 +141,8 @@ main(ac, av) f_hexdump = 1; break; case 'x': - f_promisc = 1; - promisc(); - /*NOTREACHED*/ + f_mode = MODE_PROMISC; + break; case 'P': f_policy = 1; break; @@ -170,10 +171,15 @@ main(ac, av) errx(-1, "%s", ipsec_strerror()); /*NOTREACHED*/ } - parse(&fp); + if (parse(&fp)) + exit (1); break; + case MODE_PROMISC: + promisc(); + /*NOTREACHED*/ default: Usage(); + /*NOTREACHED*/ } exit(0); @@ -216,7 +222,6 @@ sendkeyshort(type) m_msg->sadb_msg_satype = SADB_SATYPE_UNSPEC; m_msg->sadb_msg_len = PFKEY_UNIT64(m_len); m_msg->sadb_msg_reserved = 0; - m_msg->sadb_msg_reserved = 0; m_msg->sadb_msg_seq = 0; m_msg->sadb_msg_pid = getpid(); @@ -240,7 +245,6 @@ promisc() m_msg->sadb_msg_satype = 1; m_msg->sadb_msg_len = PFKEY_UNIT64(m_len); m_msg->sadb_msg_reserved = 0; - m_msg->sadb_msg_reserved = 0; m_msg->sadb_msg_seq = 0; m_msg->sadb_msg_pid = getpid(); @@ -325,8 +329,10 @@ sendkeymsg() if (f_forever) shortdump_hdr(); again: - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)m_buf); + printf("\n"); + } if ((len = send(so, m_buf, m_len, 0)) < 0) { perror("send"); @@ -345,8 +351,10 @@ again: break; } - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)rbuf); + printf("\n"); + } if (postproc(msg, len) < 0) break; } while (msg->sadb_msg_errno || msg->sadb_msg_seq); @@ -423,8 +431,10 @@ postproc(msg, len) pfkey_sadump(msg); msg = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len)); - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)msg); + printf("\n"); + } break; case SADB_X_SPDDUMP: @@ -432,8 +442,10 @@ postproc(msg, len) if (msg->sadb_msg_seq == 0) break; msg = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len)); - if (f_verbose) + if (f_verbose) { kdebug_sadb((struct sadb_msg *)msg); + printf("\n"); + } break; } diff --git a/usr.sbin/setkey/test-pfkey.c b/usr.sbin/setkey/test-pfkey.c index 849aba355a99f..b1fb238c5a412 100644 --- a/usr.sbin/setkey/test-pfkey.c +++ b/usr.sbin/setkey/test-pfkey.c @@ -1,7 +1,10 @@ +/* $FreeBSD$ */ +/* $KAME: test-pfkey.c,v 1.4 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 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: @@ -13,7 +16,7 @@ * 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 @@ -25,10 +28,7 @@ * 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$ */ -/* KAME $Id: test-pfkey.c,v 1.2 1999/10/26 08:09:17 itojun Exp $ */ #include <sys/types.h> #include <sys/param.h> @@ -47,23 +47,24 @@ #include <ctype.h> #include <unistd.h> #include <errno.h> +#include <netdb.h> -u_char m_buf[BUFSIZ]; -u_int m_len; -char *pname; +u_char m_buf[BUFSIZ]; +u_int m_len; +char *pname; -void Usage __P((void)); -int sendkeymsg __P((void)); -void key_setsadbmsg __P((u_int)); -void key_setsadbsens __P((void)); -void key_setsadbprop __P((void)); -void key_setsadbid __P((u_int, caddr_t)); -void key_setsadblft __P((u_int, u_int)); -void key_setspirange __P((void)); -void key_setsadbkey __P((u_int, caddr_t)); -void key_setsadbsa __P((void)); -void key_setsadbaddr __P((u_int, u_int, caddr_t)); -void key_setsadbextbuf __P((caddr_t, int, caddr_t, int, caddr_t, int)); +void Usage __P((void)); +int sendkeymsg __P((void)); +void key_setsadbmsg __P((u_int)); +void key_setsadbsens __P((void)); +void key_setsadbprop __P((void)); +void key_setsadbid __P((u_int, caddr_t)); +void key_setsadblft __P((u_int, u_int)); +void key_setspirange __P((void)); +void key_setsadbkey __P((u_int, caddr_t)); +void key_setsadbsa __P((void)); +void key_setsadbaddr __P((u_int, u_int, caddr_t)); +void key_setsadbextbuf __P((caddr_t, int, caddr_t, int, caddr_t, int)); void Usage() @@ -98,6 +99,18 @@ sendkeymsg() perror("socket(PF_KEY)"); goto end; } +#if 0 + { +#include <sys/time.h> + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + perror("setsockopt"); + goto end; + } + } +#endif pfkey_sadump((struct sadb_msg *)m_buf); @@ -124,11 +137,14 @@ key_setsadbmsg(type) { struct sadb_msg m_msg; + memset(&m_msg, 0, sizeof(m_msg)); m_msg.sadb_msg_version = PF_KEY_V2; m_msg.sadb_msg_type = type; m_msg.sadb_msg_errno = 0; m_msg.sadb_msg_satype = SADB_SATYPE_ESP; +#if 0 m_msg.sadb_msg_reserved = 0; +#endif m_msg.sadb_msg_seq = 0; m_msg.sadb_msg_pid = getpid(); @@ -223,6 +239,24 @@ key_setsadbmsg(type) break; case SADB_X_SPDADD: +#if 0 + { + struct sadb_x_policy m_policy; + + m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy)); + m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; + m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC; + m_policy.sadb_x_policy_esp_trans = 1; + m_policy.sadb_x_policy_ah_trans = 2; + m_policy.sadb_x_policy_esp_network = 3; + m_policy.sadb_x_policy_ah_network = 4; + m_policy.sadb_x_policy_reserved = 0; + + memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy)); + m_len += sizeof(struct sadb_x_policy); + } +#endif + case SADB_X_SPDDELETE: key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); @@ -437,32 +471,49 @@ key_setsadbaddr(ext, af, str) caddr_t str; { struct sadb_address m_addr; - u_char abuf[64]; - struct sockaddr *a = (struct sockaddr *)abuf; u_int len; + struct addrinfo hints, *res; + const char *serv; + int plen; + + switch (af) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + /* XXX bark */ + exit(1); + } /* make sockaddr buffer */ - memset(abuf, 0, sizeof(abuf)); - a->sa_len = _SALENBYAF(af); - a->sa_family = af; - _INPORTBYSA(a) = - (ext == SADB_EXT_ADDRESS_PROXY ? 0 : htons(0x1234)); - if (inet_pton(af, str, _INADDRBYSA(a)) != 1) - ; /* XXX do something */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660"); /*0x1234*/ + if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) { + /* XXX bark */ + exit(1); + } - len = sizeof(struct sadb_address) + PFKEY_ALIGN8(a->sa_len); + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen); m_addr.sadb_address_len = PFKEY_UNIT64(len); m_addr.sadb_address_exttype = ext; m_addr.sadb_address_proto = (ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP); - m_addr.sadb_address_prefixlen = _INALENBYAF(af); + m_addr.sadb_address_prefixlen = plen; m_addr.sadb_address_reserved = 0; key_setsadbextbuf(m_buf, m_len, (caddr_t)&m_addr, sizeof(struct sadb_address), - abuf, a->sa_len); + (caddr_t)res->ai_addr, res->ai_addrlen); m_len += len; + freeaddrinfo(res); + return; } diff --git a/usr.sbin/setkey/token.l b/usr.sbin/setkey/token.l index 0154beef43887..8916fdd79ee88 100644 --- a/usr.sbin/setkey/token.l +++ b/usr.sbin/setkey/token.l @@ -1,7 +1,10 @@ +/* $FreeBSD$ */ +/* $KAME: token.l,v 1.13 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 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: @@ -13,7 +16,7 @@ * 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 @@ -25,8 +28,6 @@ * 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$ */ %{ @@ -63,18 +64,19 @@ #define PREPROC DECHO CMDARG -int lineno = 1; -char cmdarg[8192]; /* XXX: BUFSIZ is the better ? */ +int lineno = 1; +char cmdarg[8192]; /* XXX: BUFSIZ is the better ? */ -extern u_char m_buf[BUFSIZ]; -extern u_int m_len; -extern int f_debug; +extern u_char m_buf[BUFSIZ]; +extern u_int m_len; +extern int f_debug; -int yylex __P((void)); -void yyerror __P((char *s)); -extern void parse_init __P((void)); -int parse __P((FILE **)); -int yyparse __P((void)); +int yylex __P((void)); +void yyfatal __P((const char *s)); +void yyerror __P((const char *s)); +extern void parse_init __P((void)); +int parse __P((FILE **)); +int yyparse __P((void)); %} @@ -106,9 +108,7 @@ decstring {digit}+ hexpair {hexdigit}{hexdigit} hexstring 0[xX]{hexdigit}+ octetstring {octet}({dot}{octet})+ -ipaddress {ipv4addr}|{ipv6addr} -ipv4addr {digit}{1,3}({dot}{digit}{1,3}){0,3} -ipv6addr {hexdigit}{0,4}({colon}{hexdigit}{0,4}){2,7}(%{letter}{letter}+)? +ipaddress [a-fA-F0-9:]([a-fA-F0-9:\.]*|[a-fA-F0-9:\.]*%[a-zA-Z0-9]*) ipaddrmask {slash}{digit}{1,3} ipaddrport {blcl}{decstring}{elcl} keyword {letter}{letter}+ @@ -186,11 +186,12 @@ lzs { PREPROC; yylval.num = SADB_X_CALG_LZS; return(ALG_COMP); } {hyphen}m { PREPROC; return(F_MODE); } transport { PREPROC; yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); } tunnel { PREPROC; yylval.num = IPSEC_MODE_TUNNEL; return(MODE); } +{hyphen}u { PREPROC; return(F_REQID); } {hyphen}f { PREPROC; return(F_EXT); } random-pad { PREPROC; yylval.num = SADB_X_EXT_PRAND; return(EXTENSION); } seq-pad { PREPROC; yylval.num = SADB_X_EXT_PSEQ; return(EXTENSION); } zero-pad { PREPROC; yylval.num = SADB_X_EXT_PZERO; return(EXTENSION); } -cyclic-seq { PREPROC; yylval.num = SADB_X_EXT_CYCSEQ; return(EXTENSION); } +nocyclic-seq { PREPROC; return(NOCYCLICSEQ); } {hyphen}r { PREPROC; return(F_REPLAY); } {hyphen}lh { PREPROC; return(F_LIFETIME_HARD); } {hyphen}ls { PREPROC; return(F_LIFETIME_SOFT); } @@ -214,35 +215,17 @@ any { PREPROC; return(ANY); } char *bp; PREPROC; - yylval.num = strtol(yytext, &bp, 10); + yylval.num = strtoul(yytext, &bp, 10); return(DECSTRING); } -{ipv4addr} { - /* - * I can't supprt the type without dot, - * because it's umbiguous against {decstring}. - * e.g. 127 - */ +{ipaddress} { PREPROC; - yylval.val.len = sizeof(struct sockaddr_in); + yylval.val.len = yyleng; yylval.val.buf = strdup(yytext); - return(IP4_ADDRESS); - } - -{ipv6addr} { -#ifdef INET6 - PREPROC; - - yylval.val.len = sizeof(struct sockaddr_in6); - yylval.val.buf = strdup(yytext); - - return(IP6_ADDRESS); -#else - yyerror("IPv6 address not supported"); -#endif + return(ADDRESS); } {ipaddrmask} { @@ -263,7 +246,6 @@ any { PREPROC; return(ANY); } } {blcl}any{elcl} { - char *p = yytext; PREPROC; return(PORTANY); } @@ -294,12 +276,24 @@ any { PREPROC; return(ANY); } return(QUOTEDSTRING); } -. { yyerror("Syntax error"); } +. { + yyfatal("Syntax error"); + /*NOTREACHED*/ + } %% void -yyerror(char *s) +yyfatal(s) + const char *s; +{ + yyerror(s); + exit(1); +} + +void +yyerror(s) + const char *s; { printf("line %d: %s at [%s]\n", lineno, s, yytext); } @@ -319,4 +313,3 @@ parse(fp) return(0); } - diff --git a/usr.sbin/setkey/vchar.h b/usr.sbin/setkey/vchar.h index 977f5f0f60d41..f3251c7bfed32 100644 --- a/usr.sbin/setkey/vchar.h +++ b/usr.sbin/setkey/vchar.h @@ -1,7 +1,10 @@ +/* $FreeBSD$ */ +/* $KAME: vchar.h,v 1.2 2000/06/07 00:29:14 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, 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: @@ -13,7 +16,7 @@ * 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 @@ -25,11 +28,9 @@ * 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$ */ typedef struct { - u_int len; - caddr_t buf; + u_int len; + caddr_t buf; } vchar_t; diff --git a/usr.sbin/traceroute6/traceroute6.8 b/usr.sbin/traceroute6/traceroute6.8 index 575c86cb727e4..38d171482d604 100644 --- a/usr.sbin/traceroute6/traceroute6.8 +++ b/usr.sbin/traceroute6/traceroute6.8 @@ -25,7 +25,6 @@ .\" 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 @@ -37,18 +36,48 @@ .Nd "print the route IPv6 packets will take to the destination" .\" .Sh SYNOPSIS -.Nm +.Nm traceroute6 +.Bk -words .Op Fl dlnrv +.Ek +.Bk -words +.Op Fl f Ar firsthop +.Ek +.Bk -words +.Op Fl g Ar gateway +.Ek +.Bk -words .Op Fl m Ar hoplimit +.Ek +.Bk -words .Op Fl p Ar port +.Ek +.Bk -words .Op Fl q Ar probes +.Ek +.Bk -words .Op Fl s Ar src +.Ek +.Bk -words .Op Fl w Ar waittime +.Ek +.Bk -words +.Ar target +.Op Ar datalen +.Ek .\" .Sh DESCRIPTION .Bl -tag -width Ds .It Fl d Debug mode. +.It Fl f Ar firsthop +Specify how many hops to skip in trace. +.It Fl g Ar gateway +Specify intermediate gateway +.Po +.Nm +uses routing header +.Pc . .It Fl m Ar hoplimit Specify maximum hoplimit. .It Fl l @@ -92,7 +121,3 @@ command will exit with 0 on success, and non-zero on errors. The .Nm command first appeared in WIDE hydrangea IPv6 protocol stack kit. -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c index 65f80e70626d7..163cf0c9259d1 100644 --- a/usr.sbin/traceroute6/traceroute6.c +++ b/usr.sbin/traceroute6/traceroute6.c @@ -1,3 +1,5 @@ +/* $KAME: traceroute6.c,v 1.29 2000/06/12 16:29:18 itojun Exp $ */ + /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. @@ -25,8 +27,6 @@ * 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$ */ /*- @@ -72,7 +72,11 @@ static char copyright[] = #endif /* not lint */ #ifndef lint +#if 0 static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93"; +#endif +static const char rcsid[] = + "$FreeBSD$"; #endif /* not lint */ /* @@ -274,26 +278,30 @@ static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93"; #include <netinet6/ipsec.h> #endif -#define freehostent(hp) -#define DUMMY_PORT 10010 +#define DUMMY_PORT 10010 #define MAXPACKET 65535 /* max ip packet size */ #ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 +#define MAXHOSTNAMELEN 64 #endif #ifndef FD_SET -#define NFDBITS (8*sizeof(fd_set)) -#define FD_SETSIZE NFDBITS -#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) -#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) -#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) -#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) +#define NFDBITS (8*sizeof(fd_set)) +#define FD_SETSIZE NFDBITS +#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) #endif -#define Fprintf (void)fprintf -#define Sprintf (void)sprintf -#define Printf (void)printf +#define Fprintf (void)fprintf +#define Sprintf (void)sprintf +#define Printf (void)printf + +#ifndef HAVE_GETIPNODEBYNAME +#define getipnodebyname(x, y, z, u) gethostbyname2((x), (y)) +#define freehostent(x) +#endif /* * format of a (udp) probe packet. @@ -309,7 +317,11 @@ struct opacket *outpacket; /* last output (udp) packet */ int main __P((int, char *[])); int wait_for_reply __P((int, struct msghdr *)); +#ifdef IPSEC +#ifdef IPSEC_POLICY_IPSEC int setpolicy __P((int so, char *policy)); +#endif +#endif void send_probe __P((int, int)); struct udphdr *get_udphdr __P((struct ip6_hdr *, u_char *)); int get_hoplim __P((struct msghdr *)); @@ -318,7 +330,7 @@ char *pr_type __P((int)); int packet_ok __P((struct msghdr *, int, int)); void print __P((struct msghdr *, int)); void tvsub __P((struct timeval *, struct timeval *)); -char *inetname __P((struct in6_addr *)); +const char *inetname __P((struct sockaddr *)); void usage __P((void)); int rcvsock; /* receive (icmp) socket file descriptor */ @@ -331,15 +343,19 @@ int rcvhlim; struct in6_pktinfo *rcvpktinfo; struct sockaddr_in6 Src, Dst, Rcv; -struct sockaddr_in6 *src = &Src, *dst = &Dst, *rcv = &Rcv; int datalen; /* How much data */ -char rtbuf[1024]; /*XXX*/ +/* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */ +char rtbuf[2064]; +#ifdef USE_RFC2292BIS +struct ip6_rthdr *rth; +#endif struct cmsghdr *cmsg; char *source = 0; char *hostname; int nprobes = 3; +int first_hop = 1; int max_hops = 30; u_short ident; u_short port = 32768+666; /* start udp dest port # for probe packets */ @@ -349,41 +365,74 @@ int waittime = 5; /* time to wait for response (in seconds) */ int nflag; /* print addresses numerically */ int lflag; /* print both numerical address & hostname */ -char ntop_buf[INET6_ADDRSTRLEN]; /* for inet_ntop() */ +#ifdef KAME_SCOPEID +const int niflag = NI_WITHSCOPEID; +#else +const int niflag = 0; +#endif int main(argc, argv) int argc; char *argv[]; { - extern char *optarg; - extern int optind; struct hostent *hp; - struct addrinfo hints, *res; int error; - int ch, i, on, probe, seq, hops; - static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) - + CMSG_SPACE(sizeof(int))]; + struct addrinfo hints, *res; + int ch, i, on, probe, seq, hops, rcvcmsglen; + static u_char *rcvcmsgbuf; + char hbuf[NI_MAXHOST], src0[NI_MAXHOST]; /* * Receive ICMP */ if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { - perror("traceroute6: icmp socket"); + perror("socket(ICMPv6)"); exit(5); } - setuid(getuid()); + /* set a minimum set of socket options */ on = 1; - seq = 0; + /* specify to tell receiving interface */ +#ifdef IPV6_RECVPKTINFO + if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, + sizeof(on)) < 0) + err(1, "setsockopt(IPV6_RECVPKTINFO)"); +#else /* old adv. API */ + if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on, + sizeof(on)) < 0) + err(1, "setsockopt(IPV6_PKTINFO)"); +#endif + + /* specify to tell value of hoplimit field of received IP6 hdr */ +#ifdef IPV6_RECVHOPLIMIT + if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, + sizeof(on)) < 0) + err(1, "setsockopt(IPV6_RECVHOPLIMIT)"); +#else /* old adv. API */ + if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, + sizeof(on)) < 0) + err(1, "setsockopt(IPV6_HOPLIMIT)"); +#endif - while ((ch = getopt(argc, argv, "dlm:np:q:rs:w:vg:")) != EOF) + /* revoke privs */ + seteuid(getuid()); + setuid(getuid()); + + seq = 0; + + while ((ch = getopt(argc, argv, "df:g:lm:np:q:rs:w:v")) != EOF) switch(ch) { case 'd': options |= SO_DEBUG; break; - case 'l': - lflag++; + case 'f': + first_hop = atoi(optarg); + if (first_hop > max_hops) { + Fprintf(stderr, + "traceroute6: min hoplimit must be <= %d.\n", max_hops); + exit(1); + } break; case 'g': hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno); @@ -392,15 +441,43 @@ main(argc, argv) "traceroute6: unknown host %s\n", optarg); exit(1); } +#ifdef USE_RFC2292BIS + if (rth == NULL) { + /* + * XXX: We can't detect the number of + * intermediate nodes yet. + */ + if ((rth = inet6_rth_init((void *)rtbuf, + sizeof(rtbuf), + IPV6_RTHDR_TYPE_0, + 0)) == NULL) { + Fprintf(stderr, + "inet6_rth_init failed.\n"); + exit(1); + } + } + if (inet6_rth_add((void *)rth, + (struct in6_addr *)hp->h_addr)) { + Fprintf(stderr, + "inet6_rth_add failed for %s\n", + optarg); + exit(1); + } +#else /* old advanced API */ if (cmsg == NULL) cmsg = inet6_rthdr_init(rtbuf, IPV6_RTHDR_TYPE_0); inet6_rthdr_add(cmsg, (struct in6_addr *)hp->h_addr, IPV6_RTHDR_LOOSE); +#endif + freehostent(hp); + break; + case 'l': + lflag++; break; case 'm': max_hops = atoi(optarg); - if (max_hops <= 1) { + if (max_hops < first_hop) { Fprintf(stderr, - "traceroute6: max hoplimit must be >1.\n"); + "traceroute6: max hoplimit must be >= %d.\n", first_hop); exit(1); } break; @@ -453,7 +530,11 @@ main(argc, argv) if (argc < 1) usage(); +#if 1 setvbuf(stdout, NULL, _IOLBF, BUFSIZ); +#else + setlinebuf (stdout); +#endif memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_INET6; @@ -464,16 +545,15 @@ main(argc, argv) if (error) { (void)fprintf(stderr, "traceroute6: %s\n", gai_strerror(error)); - if (error == EAI_SYSTEM) - (void)fprintf(stderr, - "traceroute6: %s\n", strerror(errno)); exit(1); } - if (!res->ai_addr) - errx(1, "getaddrinfo failed"); + if (res->ai_addrlen != sizeof(Dst)) { + (void)fprintf(stderr, + "traceroute6: size of sockaddr mismatch\n"); + exit(1); + } memcpy(&Dst, res->ai_addr, res->ai_addrlen); hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv; - freeaddrinfo(res); if (*++argv) datalen = atoi(*argv); @@ -486,7 +566,7 @@ main(argc, argv) datalen += sizeof(struct opacket); outpacket = (struct opacket *)malloc((unsigned)datalen); if (! outpacket) { - perror("traceroute6: malloc"); + perror("malloc"); exit(1); } (void) bzero((char *)outpacket, datalen); @@ -494,22 +574,18 @@ main(argc, argv) /* initialize msghdr for receiving packets */ rcviov[0].iov_base = (caddr_t)packet; rcviov[0].iov_len = sizeof(packet); - rcvmhdr.msg_name = (caddr_t)rcv; - rcvmhdr.msg_namelen = sizeof(*rcv); + rcvmhdr.msg_name = (caddr_t)&Rcv; + rcvmhdr.msg_namelen = sizeof(Rcv); rcvmhdr.msg_iov = rcviov; rcvmhdr.msg_iovlen = 1; + rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) { + Fprintf(stderr, "traceroute6: malloc failed\n"); + exit(1); + } rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; - rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf); - - /* specify to tell receiving interface */ - if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on, - sizeof(on)) < 0) - err(1, "setsockopt(IPV6_PKTINFO)"); - - /* specify to tell value of hoplimit field of received IP6 hdr */ - if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, - sizeof(on)) < 0) - err(1, "setsockopt(IPV6_HOPLIMIT)"); + rcvmhdr.msg_controllen = rcvcmsglen; if (options & SO_DEBUG) (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG, @@ -527,6 +603,26 @@ main(argc, argv) errx(1, ipsec_strerror()); if (setpolicy(rcvsock, "out bypass") < 0) errx(1, ipsec_strerror()); +#else + { + int level = IPSEC_LEVEL_NONE; + + (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, + sizeof(level)); + (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, + sizeof(level)); +#ifdef IP_AUTH_TRANS_LEVEL + (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level, + sizeof(level)); +#else + (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level, + sizeof(level)); +#endif +#ifdef IP_AUTH_NETWORK_LEVEL + (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level, + sizeof(level)); +#endif + } #endif /*IPSEC_POLICY_IPSEC*/ #endif /*IPSEC*/ @@ -534,25 +630,43 @@ main(argc, argv) * Send UDP */ if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - perror("traceroute6: udp socket"); + perror("socket(SOCK_DGRAM)"); exit(5); } +#ifdef SO_SNDBUF if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen, sizeof(datalen)) < 0) { - perror("traceroute6: SO_SNDBUF"); + perror("setsockopt(SO_SNDBUF)"); exit(6); } +#endif /* SO_SNDBUF */ if (options & SO_DEBUG) (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)); if (options & SO_DONTROUTE) (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, sizeof(on)); +#ifdef USE_RFC2292BIS + if (rth) {/* XXX: there is no library to finalize the header... */ + rth->ip6r_len = rth->ip6r_segleft * 2; + if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR, + (void *)rth, (rth->ip6r_len + 1) << 3)) { + Fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n", + strerror(errno)); + exit(1); + } + } +#else /* old advanced API */ if (cmsg != NULL) { inet6_rthdr_lasthop(cmsg, IPV6_RTHDR_LOOSE); - (void) setsockopt(sndsock, IPPROTO_IPV6, IPV6_PKTOPTIONS, - rtbuf, cmsg->cmsg_len); + if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_PKTOPTIONS, + rtbuf, cmsg->cmsg_len) < 0) { + Fprintf(stderr, "setsockopt(IPV6_PKTOPTIONS): %s\n", + strerror(errno)); + exit(1); + } } +#endif /* USE_RFC2292BIS */ #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC /* @@ -563,62 +677,130 @@ main(argc, argv) errx(1, ipsec_strerror()); if (setpolicy(sndsock, "out bypass") < 0) errx(1, ipsec_strerror()); +#else + { + int level = IPSEC_LEVEL_BYPASS; + + (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level, + sizeof(level)); + (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level, + sizeof(level)); +#ifdef IP_AUTH_TRANS_LEVEL + (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level, + sizeof(level)); +#else + (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level, + sizeof(level)); +#endif +#ifdef IP_AUTH_NETWORK_LEVEL + (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level, + sizeof(level)); +#endif + } #endif /*IPSEC_POLICY_IPSEC*/ #endif /*IPSEC*/ /* * Source selection */ - bzero((char *)src, sizeof(Src)); + bzero(&Src, sizeof(Src)); if (source) { - if (inet_pton(AF_INET6, source, &Src.sin6_addr) != 1) { - Printf("traceroute6: unknown host %s\n", source); + struct addrinfo hints, *res; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + error = getaddrinfo(source, "0", &hints, &res); + if (error) { + Printf("traceroute6: %s: %s\n", source, + gai_strerror(error)); exit(1); } + if (res->ai_addrlen > sizeof(Src)) { + Printf("traceroute6: %s: %s\n", source, + gai_strerror(error)); + exit(1); + } + memcpy(&Src, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); } else { struct sockaddr_in6 Nxt; int dummy, len; - len = sizeof(Src); Nxt = Dst; Nxt.sin6_port = htons(DUMMY_PORT); if (cmsg != NULL) bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr, sizeof(Nxt.sin6_addr)); if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - perror("socket") ; + perror("socket"); + exit(1); } - if(-1 == connect(dummy, (struct sockaddr *)&Nxt, sizeof(Nxt))) + if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) { perror("connect"); - if(-1 == getsockname(dummy, (struct sockaddr *)src, &len)) { + exit(1); + } + len = sizeof(Src); + if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) { perror("getsockname"); - printf("%d\n", errno); + exit(1); } - close(dummy) ; + if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len, + src0, sizeof(src0), NULL, 0, + NI_NUMERICHOST | niflag)) { + Fprintf(stderr, "getnameinfo failed for source\n"); + exit(1); + } + source = src0; + close(dummy); } + +#if 1 ident = (getpid() & 0xffff) | 0x8000; - Src.sin6_family = AF_INET6; +#else + ident = 0; /*let the kernel pick one*/ +#endif Src.sin6_port = htons(ident); - if (bind(sndsock, (struct sockaddr *)src, sizeof(Src)) < 0){ - perror ("traceroute6: bind:"); - exit (1); + if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) { + perror("bind"); + exit(1); + } + + if (ident == 0) { + int len; + + len = sizeof(Src); + if (getsockname(sndsock, (struct sockaddr *)&Src, &i) < 0) { + perror("getsockname"); + exit(1); + } + ident = ntohs(Src.sin6_port); } /* * Message to users */ - Fprintf(stderr, "traceroute to %s (%s)", hostname, - inet_ntop(AF_INET6, &Dst.sin6_addr, - ntop_buf, sizeof(ntop_buf))); + if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf, + sizeof(hbuf), NULL, 0, NI_NUMERICHOST | niflag)) + strcpy(hbuf, "(invalid)"); + Fprintf(stderr, "traceroute6"); + Fprintf(stderr, " to %s (%s)", hostname, hbuf); if (source) Fprintf(stderr, " from %s", source); - Fprintf(stderr, ", %d hops max, %d byte packets\n", max_hops, datalen); + Fprintf(stderr, + ", %d hops max, %d byte packets\n", + max_hops, datalen); (void) fflush(stderr); + if (first_hop > 1) + Printf("Skipping %d intermediate hops\n", first_hop - 1); + /* * Main loop */ - for (hops = 1; hops <= max_hops; ++hops) { + for (hops = first_hop; hops <= max_hops; ++hops) { struct in6_addr lastaddr; int got_there = 0; int unreachable = 0; @@ -712,7 +894,7 @@ setpolicy(so, policy) buf = ipsec_set_policy(policy, strlen(policy)); if (buf == NULL) { - warnx(ipsec_strerror()); + warnx("%s", ipsec_strerror()); return -1; } (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY, @@ -744,7 +926,7 @@ send_probe(seq, hops) (void) gettimeofday(&op->tv, &tz); i = sendto(sndsock, (char *)outpacket, datalen , 0, - (struct sockaddr *)dst, sizeof(Dst)); + (struct sockaddr *)&Dst, Dst.sin6_len); if (i < 0 || i != datalen) { if (i<0) perror("sendto"); @@ -834,7 +1016,7 @@ pr_type(t0) cp = "Neighbor Advertisement"; break; case ND_REDIRECT: - cp = "Ridirect"; + cp = "Redirect"; break; default: cp = "Unknown"; @@ -856,15 +1038,42 @@ packet_ok(mhdr, cc, seq) char *buf = (char *)mhdr->msg_iov[0].iov_base; struct cmsghdr *cm; int *hlimp; + char hbuf[NI_MAXHOST]; +#ifdef OLDRAWSOCKET + int hlen; + struct ip6_hdr *ip; +#endif + +#ifdef OLDRAWSOCKET + ip = (struct ip6_hdr *) buf; + hlen = sizeof(struct ip6_hdr); + if (cc < hlen + sizeof(struct icmp6_hdr)) { + if (verbose) { + if (getnameinfo((struct sockaddr *)from, from->sin6_len, + hbuf, sizeof(hbuf), NULL, 0, + NI_NUMERICHOST | niflag) != 0) + strcpy(hbuf, "invalid"); + Printf("packet too short (%d bytes) from %s\n", cc, + hbuf); + } + return (0); + } + cc -= hlen; + icp = (struct icmp6_hdr *)(buf + hlen); +#else if (cc < sizeof(struct icmp6_hdr)) { - if (verbose) - Printf("data too short (%d bytes) from %s\n", cc, - inet_ntop(AF_INET6, &from->sin6_addr, - ntop_buf, sizeof(ntop_buf))); + if (verbose) { + if (getnameinfo((struct sockaddr *)from, from->sin6_len, + hbuf, sizeof(hbuf), NULL, 0, + NI_NUMERICHOST | niflag) != 0) + strcpy(hbuf, "invalid"); + Printf("data too short (%d bytes) from %s\n", cc, hbuf); + } return(0); } icp = (struct icmp6_hdr *)buf; +#endif /* get optional information via advanced API */ rcvpktinfo = NULL; hlimp = NULL; @@ -883,9 +1092,14 @@ packet_ok(mhdr, cc, seq) } if (rcvpktinfo == NULL || hlimp == NULL) { warnx("failed to get received hop limit or packet info"); +#if 0 return(0); +#else + rcvhlim = 0; /*XXX*/ +#endif } - rcvhlim = *hlimp; + else + rcvhlim = *hlimp; type = icp->icmp6_type; code = icp->icmp6_code; @@ -906,18 +1120,31 @@ packet_ok(mhdr, cc, seq) } if (verbose) { int i; - u_long *lp = (u_long *)(icp + 1); - char sbuf[INET6_ADDRSTRLEN+1], dbuf[INET6_ADDRSTRLEN]; + u_int8_t *p; + char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN]; - Printf("\n%d bytes from %s to %s", cc, - inet_ntop(AF_INET6, &from->sin6_addr, - sbuf, sizeof(sbuf)), - inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, - dbuf, sizeof(dbuf))); + if (getnameinfo((struct sockaddr *)from, from->sin6_len, + sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST | niflag) != 0) + strcpy(sbuf, "invalid"); + Printf("\n%d bytes from %s to %s", cc, sbuf, + rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, + dbuf, sizeof(dbuf)) + : "?"); Printf(": icmp type %d (%s) code %d\n", type, pr_type(type), icp->icmp6_code); - for (i = 4; i < cc ; i += sizeof(long)) - Printf("%2d: %8.8x\n", i, (u_int32_t)ntohl(*lp++)); + p = (u_int8_t *)(icp + 1); +#define WIDTH 16 + for (i = 0; i < cc; i++) { + if (i % WIDTH == 0) + Printf("%04x:", i); + if (i % 4 == 0) + Printf(" "); + Printf("%02x", p[i]); + if (i % WIDTH == WIDTH - 1) + Printf("\n"); + } + if (cc % WIDTH != 0) + Printf("\n"); } return(0); } @@ -973,24 +1200,30 @@ print(mhdr, cc) int cc; { struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name; + char hbuf[NI_MAXHOST]; - if (nflag) { - Printf(" %s", inet_ntop(AF_INET6, &from->sin6_addr, - ntop_buf, sizeof(ntop_buf))); - } - else if (lflag) { - Printf(" %s (%s)", inetname(&from->sin6_addr), - inet_ntop(AF_INET6, &from->sin6_addr, - ntop_buf, sizeof(ntop_buf))); - } - else { - Printf(" %s", inetname(&from->sin6_addr)); - } + if (getnameinfo((struct sockaddr *)from, from->sin6_len, + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST | niflag) != 0) + strcpy(hbuf, "invalid"); + if (nflag) + Printf(" %s", hbuf); + else if (lflag) + Printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf); + else + Printf(" %s", inetname((struct sockaddr *)from)); if (verbose) { +#ifdef OLDRAWSOCKET + Printf(" %d bytes to %s", cc, + rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, + hbuf, sizeof(hbuf)) + : "?"); +#else Printf(" %d bytes of data to %s", cc, - inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, - ntop_buf, sizeof(ntop_buf))); + rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr, + hbuf, sizeof(hbuf)) + : "?"); +#endif } } @@ -1015,16 +1248,14 @@ tvsub(out, in) * If the nflag has been supplied, give * numeric value, otherwise try for symbolic name. */ -char * -inetname(in) - struct in6_addr *in; +const char * +inetname(sa) + struct sockaddr *sa; { register char *cp; - static char line[50]; - struct hostent *hp; + static char line[NI_MAXHOST]; static char domain[MAXHOSTNAMELEN + 1]; static int first = 1; - int herr; if (first && !nflag) { first = 0; @@ -1034,34 +1265,30 @@ inetname(in) else domain[0] = 0; } - cp = 0; + cp = NULL; if (!nflag) { - /* hp = (struct hostent *)addr2hostname(in, sizeof(*in), AF_INET6, &herr); */ - hp = (struct hostent *)getipnodebyaddr((const char *)in, sizeof(*in), - AF_INET6, &herr); - if (hp) { - if ((cp = index(hp->h_name, '.')) && + if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0, + NI_NAMEREQD) == 0) { + if ((cp = index(line, '.')) && !strcmp(cp + 1, domain)) *cp = 0; - cp = hp->h_name; -#undef freehostent(hp) - freehostent(hp); -#define freehostent(hp) + cp = line; } } if (cp) - (void) strcpy(line, cp); - else { - (void)inet_ntop(AF_INET6, in, line, sizeof(line)); - } - return (line); + return cp; + + if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0, + NI_NUMERICHOST | niflag) != 0) + strcpy(line, "invalid"); + return line; } void usage() { (void)fprintf(stderr, -"usage: traceroute6 [-dlnrv] [-m max_hops] [-p port#] [-q nqueries]\n\t\ -[-s src_addr] [-g gateway] [-w wait] host [data size]\n"); +"usage: traceroute6 [-dlnrv] [-f first_hop] [-m max_hops] [-p port#] \n" +" [-q nqueries] [-s src_addr] [-g gateway] [-w wait] host [data size]\n"); exit(1); } |
